サイトトップへこのカテゴリの一覧へ

X 3016:2010 (ISO/IEC 23271:2006) 

(1) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

目 次 

ページ 

序文 ··································································································································· 1 

第1章 概念及びアーキテクチャ ···························································································· 1 

1 適用範囲························································································································· 1 

2 適合性···························································································································· 2 

3 引用規格························································································································· 2 

4 形式······························································································································· 4 

4.1 構成 ···························································································································· 4 

4.2 参考情報 ······················································································································ 4 

5 用語及び定義 ··················································································································· 4 

6 共通言語基盤の概要 ·········································································································· 9 

6.1 型安全との関係 ············································································································ 10 

6.2 管理下メタデータ駆動実行との関係·················································································· 10 

7 共通言語仕様 ·················································································································· 12 

7.1 導入 ··························································································································· 12 

7.2 CLI合致についての見方 ································································································ 12 

7.3 CLS合致 ····················································································································· 14 

8 共通型システム ··············································································································· 16 

8.1 オブジェクト指向プログラムとの関係··············································································· 17 

8.2 値及び型 ····················································································································· 18 

8.3 格納域 ························································································································ 22 

8.4 型メンバ ····················································································································· 23 

8.5 名前付け ····················································································································· 24 

8.6 契約 ··························································································································· 30 

8.7 代入互換性 ·················································································································· 34 

8.8 型安全及び正当性検証 ··································································································· 35 

8.9 型定義側 ····················································································································· 36 

8.10 メンバの継承 ·············································································································· 46 

8.11 メンバ定義 ················································································································· 49 

9 メタデータ ····················································································································· 52 

9.1 構成部品及びアセンブリ ································································································ 52 

9.2 メタデータへのアクセス ································································································ 53 

9.3 管理外コード ··············································································································· 53 

9.4 メソッド実装メタデータ ································································································ 54 

9.5 クラスの配置 ··············································································································· 54 

9.6 アセンブリ,すなわち,型のための名前の有効範囲 ····························································· 55 

X 3016:2010 (ISO/IEC 23271:2006) 目次 

(2) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

ページ 

9.7 メタデータの拡張性 ······································································································ 56 

9.8 大域的,移入及び移出 ··································································································· 57 

9.9 有効範囲付けされた静的な関数又はデータメンバ ································································ 58 

10 共通言語仕様のための名前及び型の規則 ············································································ 58 

10.1 識別子 ······················································································································· 58 

10.2 多重定義 ···················································································································· 58 

10.3 演算子多重定義 ··········································································································· 59 

10.4 命名パターン ·············································································································· 62 

10.5 例外 ·························································································································· 63 

10.6 カスタム属性 ·············································································································· 63 

10.7 総称型及び総称メソッド ······························································································· 64 

11 共通言語仕様規則の集約 ································································································· 69 

12 仮想実行システム ·········································································································· 73 

12.1 提供されるデータ型 ····································································································· 73 

12.2 モジュール情報 ··········································································································· 83 

12.3 計算機状態 ················································································································· 83 

12.4 制御フロー ················································································································· 88 

12.5 代理及び遠隔処理 ······································································································· 105 

12.6 メモリモデル及び最適化 ······························································································ 105 

第2章 メタデータ定義及び意味 ·························································································· 109 

1 序論····························································································································· 109 

2 概要····························································································································· 109 

3 妥当性検証及び正当性検証 ······························································································· 109 

4 例································································································································ 110 

4.1 例Hello World ············································································································· 110 

4.2 例 ····························································································································· 111 

5 一般的な構文 ················································································································· 111 

5.1 一般的な構文記法 ········································································································ 111 

5.2 基本構文要素 ·············································································································· 112 

5.3 識別子 ······················································································································· 113 

5.4 ラベル及びラベルの並び ······························································································· 114 

5.5 16進バイトの並び ········································································································ 114 

5.6 浮動小数点数 ·············································································································· 115 

5.7 ソース行情報 ·············································································································· 115 

5.8 ファイル名 ················································································································· 115 

5.9 属性及びメタデータ ····································································································· 115 

5.10 ilasmソースファイル ·································································································· 116 

6 アセンブリ,目録及びモジュール ······················································································ 116 

6.1 モジュール,アセンブリ及びファイルの概要 ····································································· 117 

X 3016:2010 (ISO/IEC 23271:2006) 目次 

(3) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

ページ 

6.2 アセンブリの定義 ········································································································ 117 

6.3 アセンブリの参照 ········································································································ 121 

6.4 モジュールの宣言 ········································································································ 123 

6.5 モジュールの参照 ········································································································ 123 

6.6 モジュール又はアセンブリの内部の宣言··········································································· 123 

6.7 移出された型定義 ········································································································ 124 

7 型及び識別情報 ·············································································································· 124 

7.1 型 ····························································································································· 124 

7.2 組込み型 ···················································································································· 126 

7.3 利用者定義型(《型参照》)への参照················································································· 126 

7.4 プラットフォーム固有なデータ型···················································································· 127 

8 可視性,アクセス可能性及び隠ぺい ··················································································· 129 

8.1 最上位の型の可視性及び入れ子型のアクセス可能性 ···························································· 129 

8.2 アクセス可能性 ··········································································································· 129 

8.3 隠ぺい ······················································································································· 129 

9 総称性·························································································································· 130 

9.1 総称型定義 ················································································································· 131 

9.2 総称性及び再帰的継承グラフ ························································································· 132 

9.3 総称メソッド定義 ········································································································ 133 

9.4 総称型のインスタンス化 ······························································································· 133 

9.5 総称における変性 ········································································································ 134 

9.6 インスタンス化された型の代入互換性·············································································· 136 

9.7 メンバ識別情報の妥当性 ······························································································· 136 

9.8 識別情報及び結合 ········································································································ 138 

9.9 継承及び上書き ··········································································································· 138 

9.10 明示的なメソッドの上書き ··························································································· 140 

9.11 総称仮引数に対する制約 ······························································································ 141 

9.12 総称型のメンバへの参照 ······························································································ 142 

10 型の定義 ····················································································································· 142 

10.1 型ヘッダ(《クラスヘッダ》) ························································································ 142 

10.2 型定義の本体 ············································································································· 150 

10.3 仮想メソッドの導入及び上書き ····················································································· 151 

10.4 メソッド実装要件 ······································································································· 153 

10.5 特殊なメンバ ············································································································· 153 

10.6 入れ子型 ··················································································································· 157 

10.7 インスタンスの配置制御 ······························································································ 157 

10.8 大域フィールド及び大域メソッド ·················································································· 159 

11 クラスの意味 ··············································································································· 159 

12 インタフェースの意味 ··································································································· 160 

X 3016:2010 (ISO/IEC 23271:2006) 目次 

(4) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

ページ 

12.1 インタフェースの実装 ································································································· 160 

12.2 インタフェース上の仮想メソッドの実装 ········································································· 161 

13 値型の意味 ·················································································································· 162 

13.1 値型の引用 ················································································································ 163 

13.2 値型の初期化 ············································································································· 163 

13.3 値型のメソッド ·········································································································· 165 

14 特殊な型の意味 ············································································································ 166 

14.1 ベクトル ··················································································································· 166 

14.2 配列 ························································································································· 167 

14.3 enum ························································································································ 169 

14.4 ポインタ型 ················································································································ 171 

14.5 メソッドポインタ ······································································································· 173 

14.6 委譲 ························································································································· 174 

15 メソッドの定義,参照,及び呼出し ················································································· 179 

15.1 メソッド記述子 ·········································································································· 179 

15.2 静的メソッド,インスタンスメソッド及び仮想メソッド ···················································· 180 

15.3 呼出し規約 ················································································································ 181 

15.4 メソッドの定義 ·········································································································· 182 

15.5 管理外メソッド ·········································································································· 190 

16 フィールドの定義及び参照 ····························································································· 193 

16.1 フィールドの属性 ······································································································· 193 

16.2 フィールド初期化メタデータ ························································································ 195 

16.3 PEファイル中の埋込みデータ ······················································································ 196 

16.4 非リテラル静的データの初期化 ····················································································· 197 

16.5 ロード時に判明するデータ ··························································································· 198 

17 特性の定義 ·················································································································· 199 

18 イベントの定義 ············································································································ 200 

19 例外処理 ····················································································································· 203 

19.1 限定公開ブロック ······································································································· 204 

19.2 ハンドラブロック ······································································································· 204 

19.3 catchブロック ··········································································································· 204 

19.4 フィルタブロック ······································································································· 205 

19.5 finallyブロック ·········································································································· 205 

19.6 faultハンドラ ············································································································ 206 

20 セキュリティ宣言 ········································································································· 206 

21 カスタム属性 ··············································································································· 207 

21.1 CLS記法 カスタム属性使用例 ···················································································· 208 

21.2 CLIで使われる属性 ···································································································· 208 

22 メタデータ論理形式 表 ·································································································· 211 

X 3016:2010 (ISO/IEC 23271:2006) 目次 

(5) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

ページ 

23 メタデータ論理形式における他の構造体 ··········································································· 252 

23.1 ビットマスク及びフラグ ······························································································ 252 

23.2 BLOB及び識別情報 ···································································································· 258 

23.3 カスタム属性 ············································································································· 268 

23.4 組換え記述子 ············································································································· 270 

24 メタデータの物理的な配置 ····························································································· 272 

24.1 固定フィールド ·········································································································· 272 

24.2 ファイルヘッダ ·········································································································· 272 

25 PEへのファイル形式拡張 ······························································································· 277 

25.1 実行時ファイル形式の構造体 ························································································ 277 

25.2 PEヘッダ ················································································································· 278 

25.3 セクションヘッダ ······································································································· 280 

25.4 共通中間言語の物理的配置 ··························································································· 284 

第3章 CIL命令集合 ········································································································· 287 

1 有効範囲······················································································································· 287 

1.1 データ型 ···················································································································· 287 

1.2 命令変異形の表 ··········································································································· 292 

1.3 スタック推移図 ··········································································································· 297 

1.4 日本語による命令の定義 ······························································································· 297 

1.5 演算対象の型の表 ········································································································ 297 

1.6 暗黙の実引数強制型変換 ······························································································· 300 

1.7 CILコード列の制限 ····································································································· 301 

1.8 正当性検証可能性及び適正性 ························································································· 303 

1.9 メタデータトークン ····································································································· 310 

1.10 送出される例外 ·········································································································· 310 

2 命令の接頭辞 ················································································································· 310 

3 基本命令······················································································································· 316 

4 オブジェクトモデル命令 ·································································································· 356 

第4章 プロファイル及びライブラリ ···················································································· 378 

1 概要····························································································································· 378 

2 ライブラリ及びプロファイル ···························································································· 379 

2.1 ライブラリ ················································································································· 379 

2.2 プロファイル ·············································································································· 380 

2.3 ライブラリとプロファイルとの関係················································································· 380 

3 標準プロファイル ··········································································································· 381 

3.1 カーネルプロファイル ·································································································· 382 

3.2 小型プロファイル ········································································································ 382 

4 カーネルプロファイル機能要件 ························································································· 382 

4.1 カーネルプロファイルから除外される機能 ········································································ 382 

X 3016:2010 (ISO/IEC 23271:2006) 目次 

(6) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

ページ 

5 標準ライブラリ ·············································································································· 384 

5.1 一般的なコメント ········································································································ 384 

5.2 実行時基盤ライブラリ ·································································································· 384 

5.3 基底クラスライブラリ(BCL) ······················································································ 384 

5.4 ネットワークライブラリ ······························································································· 384 

5.5 自己反映ライブラリ ····································································································· 384 

5.6 XMLライブラリ ·········································································································· 385 

5.7 拡張数値ライブラリ ····································································································· 385 

5.8 拡張配列ライブラリ ····································································································· 385 

5.9 Varargライブラリ ········································································································ 385 

5.10 並列ライブラリ ·········································································································· 385 

6 システムライブラリに対する実装固有の変更 ······································································· 386 

7 XML仕様 ····················································································································· 387 

7.1 意味規則 ···················································································································· 387 

7.2 XMLにおける識別情報の記法の問題点 ············································································ 396 

第5章 デバッグ情報交換形式 ····························································································· 398 

1 可搬性CILDBファイル ··································································································· 398 

1.1 整数の符号化 ·············································································································· 398 

1.2 CILDBヘッダ ············································································································· 398 

1.3 表及びヒープ ·············································································································· 399 

1.4 識別情報 ···················································································································· 401 

第6章 附属書 ·················································································································· 402 

附属書A(参考)有効範囲 ··································································································· 402 

附属書B(参考)見本プログラム ·························································································· 403 

附属書C(参考)CILアセンブラの実装 ················································································· 417 

附属書D(参考)クラスライブラリの設計ガイドライン ···························································· 476 

附属書E(参考)可搬性に関する考察····················································································· 477 

附属書F(参考)厳密でない違反 ··························································································· 479 

附属書G(参考)並列ライブラリ ·························································································· 484 

索引 ································································································································· 487 

X 3016:2010 (ISO/IEC 23271:2006) 目次 

(7) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

まえがき 

この規格は,工業標準化法第14条によって準用する第12条第1項の規定に基づき,一般社団法人情報

処理学会(IPSJ)及び財団法人日本規格協会(JSA)から,工業標準原案を具して日本工業規格を改正す

べきとの申出があり,日本工業標準調査会の審議を経て,経済産業大臣が改正した日本工業規格である。

これによって,JIS X 3016:2006は改正され,この規格に置き換えられた。 

この規格は,著作権法で保護対象となっている著作物である。 

この規格の一部が,特許権,出願公開後の特許出願,実用新案権又は出願公開後の実用新案登録出願に

抵触する可能性があることに注意を喚起する。経済産業大臣及び日本工業標準調査会は,このような特許

権,出願公開後の特許出願,実用新案権及び出願公開後の実用新案登録出願にかかわる確認について,責

任はもたない。 

X 3016:2010 (ISO/IEC 23271:2006)

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

日本工業規格 

JIS 

X 3016:2010 

(ISO/IEC 23271:2006) 

共通言語基盤(CLI) 

CLI: Common Language Infrastructure 

序文 

この規格は,2006年に第2版として発行されたISO/IEC 23271を基に,技術的内容及び構成を変更する

ことなく作成した日本工業規格である。 

なお,この規格で点線の下線を施してある参考事項は,対応国際規格にはない事項である。 

第1章 概念及びアーキテクチャ 

適用範囲 

この規格は,異なるシステム環境で,それらの環境の独特な性質を考慮に入れた書換えを行うことなく,

複数の高水準言語で書かれたアプリケーションを動作させることを可能とする共通言語基盤(CLI)を定

義する。 

この規格は次の部分からなる。 

− 第1章 概念及びアーキテクチャ ― ここでは,CLIのアーキテクチャの総覧をし,共通型システ

ム(CTS),仮想実行システム(VES)及び共通言語仕様(CLS)について規定する。さらに,メタデ

ータについての参考情報を示す。 

− 第2章 メタデータ定義及び意味 ― ここでは,メタデータについて規定する。その(ファイル形

式としての)物理的な配置,その論理的な内容(複数の表の集合及び表間の関係)並びにその(仮想

アセンブラとしてのilasmから見た)意味を規定する。 

− 第3章 CIL命令集合 ― ここでは,共通中間言語(Common Intermediate Language,CIL)命令集

合について規定する。 

− 第4章 プロファイル及びライブラリ ― ここでは,CLIライブラリの概要を示し,これをプロフ

ァイル及びライブラリへ分割する仕様を規定する。ECMA 335及びISO 23271:2006から入手可能な,

XML書式で配布されるCLILibrary.xmlはCLIライブラリの各クラス,値型及びインタフェースの詳細

を規定する。  

− 第5章 デバッグ情報交換形式 

− 第6章 附属書 次を含む。 

− アセンブリ言語(ILAsm)で書かれた幾つかのサンプルプログラム。 

− アセンブラの特定の実装に関する情報。 

− CIL命令集合の機械可読記述。このアセンブラによって使用される文法の一部を派生するために使

用する。また,CILを操作する他のツールも使用する。 

− 第4章のライブラリの設計の中で使用されたガイドライン。 

− 移植における考慮事項 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

注記 この規格の対応国際規格及びその対応の程度を表す記号を,次に示す。 

ISO/IEC 23271:2006,Information technology−Common Language Infrastructure (CLI) Partitions I to 

VI(IDT) 

なお,対応の程度を表す記号“IDT”は,ISO/IEC Guide 21-1に基づき,“一致している”こ

とを示す。 

適合性 

この規格への適合性を表明するシステムは,この規格の必す(須)要件をすべて実装しなければならな

いし,それが実装するプロファイル(第4章参照)を指定しなければならない。最小実装はカーネルプロ

ファイルとする。さらに,規格適合処理系は,プロファイルだけに依存する書かれた現行のコードを妨げ

ないのであれば,補足機能を取り込むことができる。例えば,規格適合処理系は追加のクラス,既存のク

ラス上の新しいメソッド又は標準化されたクラス上の新しいインタフェースを提供できる。しかし,処理

系はこの規格の中で指定されたインタフェースへメソッド又は特性を加えてはならない。 

共通中間言語(第3章参照)を生成しこの規格への適合性を表明するコンパイラは,この規格の中で指

定された形式での出力ファイルを作成しなければならない。また,それが生成するCILはこの規格の中で

指定されるような正しいCILでなければならない。そのようなコンパイラは,更にそれが正当性検証可能

なコードを生成すると表明することができる。その場合には,コンパイラが生成するCILは,この規格の

中で規定されるように正当性検証可能でなければならない。 

引用規格 

次に掲げる規格は,この規格に引用されることによって,この規格の規定の一部を構成する。これらの

引用規格のうちで,西暦年を付記してあるものは,記載の年の版を適用し,その後の改正版(追補を含む。)

は適用しない。西暦年の付記がない引用規格は,その最新版(追補を含む。)を適用する。 

注記 これらの参照の多くは,クラスライブラリのXML記述の中で引用される。 

JIS X 0304:1999 国名コード 

注記 対応国際規格:ISO 3166-1:1997,Codes for the representation of names of countries and their 

subdivisions−Part 1: Country codes (IDT) 

JIS X 0412-1:2004 言語名コード−第1部:2文字コード 

注記 対応国際規格:ISO 639-1:2002,Codes for the representation of names of languages−Part 1: 

Alpha-2 code (MOD) 

JIS X 0412-2:2004 言語名コード−第2部:3文字コード 

注記 対応国際規格:ISO 639-2:1998,Codes for the representation of names of languages−Part 2: 

Alpha-3 code (MOD) 

JIS X 3014:2003 プログラム言語C++ 

注記 対応国際規格:ISO/IEC 14882:2003,Programming languages−C++ (IDT) 

JIS X 4159 拡張可能なマーク付け言語(XML)1.0 

注記 Extensible Markup Language (XML) 1.0 (Third Edition), 2004 February 4,  

http://www.w3.org/TR/2004/REC-xml-20040204/が,この引用規格と対応している。 

IEC 60559:1989,Binary floating-point arithmetic for microprocessor systems(従前の番号は,IEC 559:1989。

この規格は,米国規格ANSI/IEEE Standard 754-1985,IEEE Standard for Binary Floating-Point 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

Arithmeticとしてよく知られている。) 

Federal Information Processing Standard (FIPS 180-1), Secure Hash Standard (SHA-1), 1995, April. 

次の規格は,参考とする。 

JIS X 0201 7ビット及び8ビットの情報交換用符号化文字集合 

注記 対応国際規格:ISO/IEC 646:1991,Information technology−ISO 7-bit coded character set for 

information interchange (MOD) 

JIS X 0221 国際符号化文字集合(UCS) 

注記 対応国際規格:ISO/IEC 10646 Information technology−Universal Multiple-Octet Coded 

Character Set(UCS)(IDT) 

JIS X 3010:2003 プログラム言語C 

注記 対応国際規格:ISO/IEC 9899:1999,Programming languages−C (IDT) 

JIS X 3015:2008 プログラム言語C# 

注記 対応国際規格:ISO/IEC 23270:2006,Information technology−Programming languages−C# (IDT) 

JIS X 5718 開放型システム間相互接続−遠隔手続呼出し 

注記 対応国際規格:ISO/IEC 11578:1996,Information technology−Open Systems Interconnection−

Remote Procedure Call (RPC), Annex A: Universal Unique Identifier (IDT) 

RFC-768, User Datagram Protocol. J. Postel. 1980, August. 

RFC-791, Internet Protocol, Darpa Internet Program Protocol Specification. 1981, September. 

RFC-792, Internet Control Message Protocol, Darpa Internet Program Protocol Specification. Network Working 

Group. J. Postel. 1981, September. 

RFC-793, Transmission Control Protocol, Darpa Internet Program Protocol Specification. J. Postel. 1981, 

September. 

RFC-919, Broadcasting Internet Datagrams. Network Working Group. J. Mogul. 1984, October. 

RFC-922, Broadcasting Internet Datagrams in the presence of Subnets. Network Working Group. J. Mogul. 

1984, October. 

RFC-1035, Domain Names - Implementation and Specification. Network Working Group. P. Mockapetris. 1987, 

November. 

RFC-1036, Standard for Interchange of USENET Messages, Network Working Group. M. Horton and R. 

Adams. 1987, December. 

RFC-1112, Host Extensions for IP Multicasting. Network Working Group. S. Deering 1989, August. 

RFC-1222, Advancing the NSFNET Routing Architecture. Network Working Group. H-W Braun, and Y. 

Rekhter. 1991, May. ftp://ftp.isi.edu/in-notes/rfc1222.txt 

RFC-1510, The Kerberos Network Authentication Service (V5). Network Working Group. J. Kohl and C. 

Neuman. 1993, September. 

RFC-1741, MIME Content Type for BinHex Encoded Files. Network Working Group. P. Faltstrom, D. Crocker, 

and E. Fair. 1994, December. 

RFC-1764, The PPP XNS IDP Control Protocol (XNSCP). Network Working Group. S. Senum. 1995, March. 

RFC-1766, Tags for the Identification of Languages. Network Working Group. H. Alvestrand. 1995, March. 

RFC-1792, TCP/IPX Connection Mib Specification. Network Working Group. T. Sung. 1995, April. 

RFC-2236, Internet Group Management Protocol, Version 2. Network Working Group. W. Fenner. 1997, 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

November. 

RFC-2045, Multipurpose Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies. 

Network Working Group. N. Freed. 1996, November. 

RFC-2616, Hypertext Transfer Protocol−HTTP/1.1. Network Working Group. R. Fielding, J. Gettys, J. Mogul, 

H. Frystyk, L. Masinter, P. Leach, and T. Berners-Lee. 1999 June. ftp://ftp.isi.edu/in-notes/rfc2616.txt 

RFC-2617, HTTP Authentication: Basic and Digest Access Authentication. Network Working Group. J. Franks, 

P. Hallam-Baker, J. Hostetler, S. Lawrence, P. Leach, A. Luotonen, and L. Stewart. 1999 June,  

ftp://ftp.isi.edu/in-notes/rfc2617.txt 

The Unicode Consortium. The Unicode Standard, Version 4.0, The Unicode Standard, Version 4.0 (Boston, MA, 

Addison-Wesley, 2003. ISBN 0-321-18578-1) 

形式 

4.1 

構成 

この規格の章立ては階層構造を用いて構成される。最上位には,章がある。次に,箇条及び細分箇条が

続く。 

4.2 

参考情報 

この規格は,実装側,研究者及びアプリケーションプログラマによって使用されるように意図されてい

る。そのため,厳密にいえば,正式な規定としては不必要な説明も含む。 

例は,記述された構築の具体的な形式を例示するために提供される。参照は関連する箇条を参照するた

めに使用される。注記は実装側又はプログラマに助言又は手引を与えるために提供される。附属書は追加

情報を提供する。 

用語及び定義 

5.1 

ANSI文字(ANSI character) 

実装定義による8ビットの文字集合の文字であり,その最初の128個の符号位置は,JIS X 0221に正確

に対応する文字。 

5.2 

ANSI 文字列(ANSI string) 

ANSI文字からなる文字列であり,最後の文字は,すべてのビットが0である値をもつ文字列。 

5.3 

アセンブリ(assembly) 

1単位機能を実装するロード可能なコードモジュール及び他の資源によって構成された集合。 

5.4 

属性(attributes) 

記述的情報を含む型及び/又は型のメンバの特徴。 

注記 最も典型的な属性は,あらかじめ定義されていて,それに関連付けられたメタデータの中に,

特定の符号化されたものとして含まれるが,利用者定義の属性をメタデータへ追加することも

できる。 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

5.5 

実装固有の動作(behavior, implementation-specific) 

それぞれの実装が行った選択を文書として明記する必要がある未規定の動作。 

5.6 

未規定の動作(behavior, unspecified) 

適格なプログラム構築要素及び正しいデータに対する動作であって,振る舞いが実装に依存する動作。 

注記 その実装は,どんな動作が起こるかを文書として明記する必要はない。 

5.7 

未定義の動作(behavior, undefined) 

不正なプログラム構築要素又は不正なデータを使用したために起こり得る動作であり,この規格では要

件を定めない動作。 

注記 未定義の動作は,この規格が明確な動作の定義を省略した場合にも起こり得る。 

5.8 

ボックス化(boxing) 

値型の値を,参照型であるSystem.Objectの新しく割り付けられたインスタンスへ変換すること。 

5.9 

共通中間言語[Common Intermediate Language(CIL)] 

VESによって理解される命令セット。 

5.10 

共通言語基盤[Common Language Infrastructure(CLI)] 

実行可能コードの形式及びそのコードを実行できる実行時環境のための規定。 

5.11 

共通言語仕様[Common Language Specification(CLS)] 

言語設計者とフレームワーク(クラスライブラリ)設計者との間の合意事項。 

注記 CTSの部分集合及び使用規約を規定する。 

5.12 

共通型システム[Common Type System(CTS)] 

コンパイラ,ツール及びCLI自体によって共有される単一の型システム。 

注記 型を宣言し,使用し,管理する場合に,CLIが従う規則を定義するモデルとする。CTSは,プ

ログラム言語をまたぐ統合,型安全及び高い性能のコード実行を可能にするフレームワークを

確立する。 

5.13 

委譲(delegate) 

参照型であり,そのインスタンスは呼出し並びの中に一つ以上のメソッドをカプセル化することができ

るもの。 

注記 委譲インスタンスと適切な引数の集合とが与えられた場合,その引数の集合を用いて,委譲の

呼出し並びの中のすべてのメソッドを呼び出すことができる。 

5.14 

イベント(event) 

オブジェクト又はクラスによる通知の提供を可能にするメンバ。 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

5.15 

実行エンジン(Execution Engine) 

仮想実行システムを参照。 

5.16 

フィールド(field) 

プログラムのデータを格納する,型付けされたメモリの位置を指し示すメンバ。 

5.17 

ガーベジコレクション(garbage collection) 

管理下データのためのメモリが,割り付けられ解放される処理。 

5.18 

総称実引数(generic argument) 

特定の総称型又は総称メソッドをインスタンス化するために使用される実際の型。 

注記 例えば,List<string> の場合のstringは,総称型の定義List<T> の総称仮引数Tに対

応する総称実引数である。 

5.19 

総称仮引数(generice parameter) 

総称型又は総称メソッドの定義において,総称実引数のための場所取りとして動作する仮引数。 

注記 例えば,総称型の定義 List<T> におけるTは,総称仮引数である。 

5.20 

総称性(generics) 

一つ以上の総称仮引数による引数化された型及びメソッドの定義を可能にする機能。 

5.21 

ライブラリ(library) 

型の集合を一つ以上のアセンブリに区分けして貯蔵したもの。 

注記 ライブラリは,他のライブラリで定義した型に関する更新を含むこともできる。例えば,ライ

ブラリは,他のライブラリに定義された型に関する,追加のメソッドやインタフェース,例外

を含むことができる。 

5.22 

管理下コード(managed code) 

CLI が主要なサービスの集合を提供することを可能にする十分な情報を含むコード。 

注記 例えば,コードの中のメソッドを指し示すアドレスが与えられると,メソッドを説明するメタ

データをCLIは特定できなければならない。また,CLIは,スタックをたどり,例外に対処し,

セキュリティ情報を取り出すことができなければならない。 

5.23 

管理下データ(managed data) 

管理下データは,ガーベジコレクションと呼ばれる処理を通じて,CLIによって自動で割り付けられ解

放されるデータ。 

5.24 

目録(manifest) 

あるアセンブリの一部であって,そのアセンブリに関する次の情報を指定するもの。 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

− その版,名前,文化圏,及びセキュリティの要件 

− もしあれば,そのアセンブリに属する別のファイル,及びそれぞれのファイルの暗号化ハッシュ 

− アセンブリの中の他のファイルに定義された型で,そのアセンブリから移出されるもの 

− 省略可能なものとして,目録自身のデジタル署名,及びそれを計算するために使用される公開かぎ(鍵) 

5.25 

メンバ(member) 

型のフィールド,配列要素,メソッド,特性,及びイベントのいずれか。 

5.26 

メタデータ(metadata) 

CTS(共通型システム)によって定義された型について記述参照するデータ。 

注記 メタデータは,特定のプログラム言語に依存しない方法で格納され,“永続化”される。したが

って,メタデータは,ツールと仮想実行システムとの間だけでなくプログラムを操作するツー

ル(コンパイラ,デバッガなど)の間においても,共通の交換機構を提供する。 

5.27 

メソッド(method) 

正確な型の値に基づいて行うことができる操作を記述するメンバ。 

5.28 

総称メソッド(method, generic) 

型の中で定義され,型自身には現れない一つ以上の型仮引数をその識別情報にもつメソッド(静的メソ

ッド,インスタンスメソッド,又は仮想メソッドであってもかまわない。)。 

注記 取り囲む型は,総称又は総称でない場合がある。例えば,総称型List<T>の中で,総称メソッ

ドConbertTo<S>()は総称である。 

5.29 

総称でないメソッド(method, non-generice) 

総称メソッドではないメソッド。 

5.30 

モジュール(module) 

VESによって実行される単一ファイル。 

5.31 

オブジェクト(object) 

参照型のインスタンス。 

注記 オブジェクトは,値よりも多くをもつ。オブジェクトは,それ自体,型付けされている。すな

わち,その型は,明示的にその表現の中に含まれている。オブジェクトは,それを他のすべて

のオブジェクトと識別する同一性(識別性)をもち,(オブジェクト又は値のいずれかであって

よい)他の実体を格納するスロットをもつ。そのスロットの内容は変化してもよいが,オブジ

ェクトの同一性は決して変化しない。 

5.32 

プロファイル(profile) 

一定の水準の機能を提供する統一体となるようにひとまとめにされた,ライブラリの集合。 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

5.33 

特性(property) 

名前付きの値と,その値にアクセスする複数のメソッドとを定義したメンバ。 

注記 特性は,その値にアクセスする契約を定義する。よって,特性の定義は,存在するアクセスメ

ソッド及びそれぞれのメソッドの契約を指定する。 

5.34 

識別情報(signature) 

検査可能であって自動的に強制実行可能な契約の一部。 

注記 識別情報は,型及び他の識別情報に制約を加えて作られる。この制約は,値又は格納域の,使

用方法に関する制限又は許される操作に関する制限とする。 

5.35 

総称型(type, generic) 

一つ以上の他の型によって,その定義が引数化された型。例えば,Tが総称仮引数であるList<T>。 

注記 CLIは,総称型のインスタンスの生成と使用を提供する。例えば,List<int32>又はList<string>。 

5.36 

参照型(type, reference) 

そのインスタンスがデータの参照を含む型。 

5.37 

値型(type, value) 

そのインスタンスがそのデータ全体を直接的に含む型。 

5.38 

ボックス化解除(unboxing) 

実行時型が値型であるSystem.Object型の値を値型インスタンスに変換する操作。 

5.39 

管理外コード(unmanaged code) 

管理下にないコード。 

5.40 

管理外データ(unmanaged data) 

管理下にないデータ。 

5.41 

値(value) 

整数又は浮動小数点数のような簡単なビットパターン。 

注記 各値は,それが占める領域を記述するための型及びそのビット表現での意味をもち,また,そ

の表現において行うことができる操作ももつ。値は,各プログラム言語での単純な値及びオブ

ジェクトでないデータを表すことを意図している。 

5.42 

正当性検証(verification) 

CILコード列がプログラムの論理アドレス空間の外側のメモリへのアクセスを与えないことを保証する

ための,CIL及びその関連メタデータの両方に対する検査。 

注記 妥当性検証とともに,正当性検証は,プログラムがアクセスを許可されていないメモリ及びそ

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

の他のリソースにアクセスできないことを保証する。 

5.43 

仮想実行システム[Virtual Execution System(VES)] 

CTSのモデルを実装し,実行するシステム。 

注記 VESは,CLI向けに書かれたプログラムを読み込み,実行する責任をもつ。VESは,個別に作

成されたモジュールを実行時に一つにつなぐためのメタデータを用いて,管理下コード及び管

理下データを実行する上で必要なサービスを提供する。VES は,実行エンジンとしても知られ

ている。 

共通言語基盤の概要 

共通言語基盤(CLI)は,実行可能なコード,及びそれが動作する実行環境(仮想実行システム)につ

いて規定する。実行可能なコードはモジュールとしてVESに入力される。モジュールは,単一のファイル

で,実行可能な内容物を第2章で規定される形式で含む。 

注記 

この箇条(6.2.3まで)は参考情報であり規定ではない。 

共通言語基盤(CLI)の中心に,共通型システム(CTS)という名の統合型システムがあり,それはコン

パイラ,ツール及びCLI自体が共有する。それは,型を宣言し,使用し,管理する場合,CLIが従う規則

を定義するモデルとする。CTSは,言語間統合,型安全及び高性能コード実行を可能にするフレームワー

クを確立する。この箇条は,CTSについての記述によってCLIのアーキテクチャについて記述する。 

この箇条では,次の四つの領域について説明する。 

− 共通型システム(CTS) 共通型システム(CTS)は,多くのプログラム言語に存在する型及び操作を

実現する豊富な型システムを提供する。共通型システムは,広範囲のプログラム言語の完全な実装を

実現するように意図されている。箇条8参照。 

− メタデータ CLIは,共通型システムによって定義された型について記述し引用する目的でメタデー

タを使用する。メタデータは,任意の特定のプログラム言語に依存しない方法で格納される(“永続化

される”)。したがって,メタデータは,これらのツールと仮想実行システムとの間の共通の交換機構

であるのと同様に,プログラムを操作するツール(コンパイラ,デバッガなど)間の使用に共通の交

換機構を供給する。箇条9を参照する。 

− 共通言語仕様(CLS) 共通言語仕様は言語設計者及びフレームワーク(クラスライブラリ)設計者の

間の協定である。それは,CTS型システムの部分集合及び利用規約を規定する。CLSの一部分である

CTSの部分さえ実装すれば,言語は,利用者に対してフレームワークへのアクセスに関する最大の能

力を提供する。同様に,フレームワークは,その公開される側面(クラス,インタフェース,メソッ

ド,フィールドなど)がCLSの一部である型だけを使用し,かつ,CLS規定を遵守している場合に,

最も使われやすくなる。箇条10を参照する。 

− 仮想実行システム(VES) 仮想実行システム(VES)はCTSモデルを実装し強制する。VESは,CLI

のために書かれたプログラムのロード及び実行を行う。それは,管理下コード及び管理下データを実

行するために必要とされるサービスを提供する。別々に生成されたモジュールを,実行時にともに結

合させる(遅延結合)ためにメタデータを使用する。箇条12を参照する。 

CLIのこれらの側面は,分散コンポーネント及びアプリケーションを設計し,開発し,配置し,実行す

るための統一フレームワークを形作る。共通型システムの適切な部分集合はCLIを対象とする各プログラ

ム言語から使用可能である。アプリケーションを構築するために使用される型を定義し参照するメタデー

10 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

タを使用することによって,言語を基礎としたツールは互いに連携し,また,仮想実行システムと連携す

る。仮想実行システムは,必要に応じて型のインスタンスを生成し,かつ,基盤(遠隔処理サービス,ア

センブリのダウンロード,セキュリティなど)の他の一部にデータ型情報を供給するためにメタデータを

使用する。 

6.1 

型安全との関係 

型安全は,通常,何を行うかという観点又は何を行わせないかという観点から論じられる。前者の例と

しては,異なるオブジェクト間のカプセル化の保証がある。後者の例としては,書かれるべきでないとこ

ろに書かれたことによるメモリの破壊の防止がある。しかし,共通型システムの観点から,型安全は次を

保証する。 

− 参照は,宣言とおりのものとする。すべての参照は型づけされ,参照されたオブジェクト又は値も型

をもつ。そして,それらは代入互換とする(8.7参照)。 

− 識別性はごまかせない。オブジェクトを改ざん(竄)したりだましたりする方法はなく,したがって,

利用者又はセキュリティ領域を改ざん(竄)したりだましたりする方法はない。オブジェクトへのア

クセスは,アクセス可能な関数及びフィールドを通じて行われる。オブジェクトは,セキュリティが

危険にさらされるような方法で設計され得る。しかし,クラスのすべての利用の大域分析を行わなく

ても,クラス,そのメソッド及びそのクラスが使用するものの局所分析を行うだけで,ぜい弱性を十

分に調査評価できる。 

− 適切な操作だけを呼び出すことが可能とする。参照型はアクセス可能な関数及びフィールドを定義す

る。これは参照がどこにあるかに基づいた可視性を限定することを含んでいる。例えば下位クラスに

おいてだけ可視の限定公開のフィールドが挙げられる。 

共通型システムは型安全を促進する。例えば,あらゆるものが型づけされている。型安全は強制しても

よい。実装が型安全宣言に適合するかどうかを決めるのは難しい問題である。宣言は,プログラムのコン

パイルされた形式を備えたメタデータとして利用されるから,共通中間言語(CIL)からプラットフォー

ムコード(8.8参照)に変換するコンパイラは,実装を型検査することが可能である。 

6.2 

管理下メタデータ駆動実行との関係 

メタデータは,コードが定義する型と,コードが外部的に参照する型とを記述することによってコード

を記述する。コードが作成される場合,コンパイラはメタデータを生成する。次のために,十分な情報が

メタデータに格納される。 

− コード実行の管理 単にロード,実行するだけでなく,メモリ管理及び実行状態検査を行う。 

− コードの管理 インストール,解決及び他のサービスを管理する。 

− コード内の型の参照 他の言語及びツールへのインポート,並びに,スクリプティング及び自動化の

実現。 

共通型システムは,実行環境がメタデータで駆動されることを前提としている。メタデータの使用は,

CLIが次を実現することを可能にする。 

− 多重実行モデル メタデータによって更に実行環境は,逐次解釈コード,JIT(Just In Time)実行コー

ド,プラットフォーム固有コード及びレガシーコードの混合を取り扱うことが可能になり,デバッガ,

プロファイラなどのツールに対して,一様なサービス,すなわち,一貫性例外処理,スタック巻戻し

(unwinding),信頼性のあるコードアクセスセキュリティ,及び効率的なメモリ管理,を提供するこ

とが可能になる。 

− サービスの自動実現 メタデータが実行時に使用可能であるから,実行環境及び基底ライブラリは,

11 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

プログラマ側の努力をほとんど必要とせずに,自動的に,自己反映,自動化,シリアル化,遠隔オブ

ジェクト,及び既存の管理外プラットフォーム固有コードとの相互運用性の実現を可能とする。 

− より良い最適化 物理的なオフセット,配置及び大きさの代わりにメタデータ参照を使用することに

よって,CLIがメンバ及び割当表の物理的な配置を最適化することを可能にする。さらに,これは,

特定のCPU又は環境に合わせた生成コードの最適化が行われることを可能にする。 

− 結合のぜい弱性の軽減 メタデータ参照を使用することによって,コンパイル時オブジェクト配置を

実行時オブジェクト配置に置き換え,また,ロード時の名前による結合に置き換えることによって,

版から版に移る場合のぜい弱性を軽減する。 

− 柔軟性のある配備解決 型の参照及び型の定義の両方用のメタデータをもつことができるから,より

信頼性が高く,かつ,より柔軟性のある,配備機構及び解決機構が可能となる。解決とは,適正な場

所の集合を調べることによって,使えるための要件を,ある文脈中で最適に満たす実装を見つけるこ

とができることをいう。この解決の意味の中に含まれる五つの要素は,次のようにして得られる。ま

ず,メタデータによって二つの要素,すなわち,要件及び文脈,が使用可能になる。アプリケーショ

ンのパッケージ及び配備から,その他の三つの要素,すなわち,調査すべき適正な場所,実装を見つ

ける方法及び実装の最適性を決定する方法,が定まる。 

6.2.1 

管理下コード 

管理下コードは,CLIが取り込んで,次を含むコアサービスの一集合を提供することを可能にするため

に十分な情報を提供するコードとする。 

− メソッドのためのコードの内部のアドレスを与えられて,メソッドについて記述するメタデータを見

つける。 

− スタックをたどる。 

− 例外を扱う。 

− セキュリティ情報を格納し取り出す。 

この規格は,管理下コードの特定の命令集合,共通の中間言語(第3章CIL参照)及び管理下コードの

格納及び送信のためのファイル形式(第2章参照)を規定する。 

6.2.2 

管理下データ 

管理下データはガーベジコレクションと呼ばれる処理を通じて,CLIによって自動で割り付けられ解放

されるデータとする。 

6.2.3 

概要 

共通型システムは言語間の統合に関係している。すなわち,別の言語のオブジェクトをあたかも自らの

言語のもののように使用できるようにしている。 

CLIの目的は,任意の言語を使って,ソフトウェア部品及びアプリケーションを作成することをより容

易にすることである。CLIは,型の標準集合を定義し,すべてのソフトウェア部品をすべて自己記述とし,

高性能の共通の実行環境を提供することによって,その目的を達成する。これは,すべてのCLI合致のシ

ステムサービス及びソフトウェア部品が,すべてのCLI実現言語及びツールからアクセス可能になること

を保証する。さらに,これは,それらを使用するソフトウェア部品及びアプリケーションの配備を単純化

し,並びにコンパイラと他のツールとによって高機能実行環境に強化する方法を単純化する。共通型シス

テムは,すべての可能性を生み出す概念及び相互作用を高水準に包含する。 

その記述は,四つの領域に及ぶ。 

− 型システム 型の状態及びそれらを定義する方法。 

12 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

− メタデータ 型はどのように記述されるか,また,それらの記述がどのように格納されるか。 

− 共通言語仕様 言語相互運用性に必要な制限。 

− 仮想実行システム コードはどのように実行され,型はどのようにインスタンス化し,相互作用し,

消去されるか。 

共通言語仕様 

7.1 

導入 

共通言語仕様(CLS)は,言語相互運用性を推進することを意図した規則の一集合とする。CLSに適合

するためにはこれらの規則に従わなければならない。それらは,後続の箇条によって詳細に記述され,箇

条11で要約される。CLS合致性は,CLIの実装上で実行するために生成される型の特徴とする。そのよう

な型はCLS規則に加えてCLI規格に適合しなければならない。これらの追加の規則は,型が定義されてい

るアセンブリの外部に対して可視性がある型にだけ適用する,また,アセンブリの外部からアクセス可能

なメンバ,すなわち,可視性が“公開”のメンバ,“ファミリ”の(しかし封印型でない)メンバ又は“フ

ァミリ又はアセンブリ”の(しかし封印型でない)メンバに適用する。 

注記 CLS合致のコードからなるライブラリはここに“フレームワーク”と呼ばれる。CLIのための

コードを生成するコンパイラには,そのようなライブラリを利用できるが,作成又は拡張でき

ないように設計できる。そのようなコンパイラは“使用側”と呼ばれる。フレームワークを作

成し,かつ,拡張することを目指しているコンパイラは“拡張側”と呼ばれる。各CLS規則の

記述では,付加的な参考情報は,規則のこれらの各々の状況に対する含意を読者が理解するの

を支援するために提供される。 

7.2 

CLI合致についての見方 

注記 7.2,7.2.1及び7.2.2は参考情報であり規定ではない。 

CLSは生成されたアセンブリに適用される規則の一集合とする。CLSはライブラリとそれらを記述する

高水準プログラム言語との相互運用性を実現するために設計されているから,アセンブリの生成の過程内

で使用される,高水準のソースコード及びツールの観点からCLS規則について考えることは多くの場合有

用である。この理由から,ツール及び利用者の幾つかの異なるクラスについてのルールの暗黙的な側面を

読者が理解するのを支援するため,参考となる注記をCLS規則の記述に加える。記述の中で使用される異

なる観点は,フレームワーク,使用側及び拡張側と呼ばれ,ここで説明される。 

7.2.1 

CLSフレームワーク 

CLS合致のコードからなるライブラリはこの規格では“フレームワーク”と呼ばれる。フレームワーク

(ライブラリ)は,CLS使用側言語及び拡張側言語の両方を取り込む広範囲のプログラム言語及びツール

によって使用される目的で設計される。CLSの規則を厳守することによって,ライブラリ作成者は,ライ

ブラリが,それらがCLS規則を厳守しないことに決めた場合より,大きなツールクラスによって使用可能

になることを保証する。次はCLS合致のフレームワークが従うのが望ましい幾つかの追加の手引とする。 

− プログラム言語の中でキーワードとして一般に使用される名前の使用を回避するのが望ましい。 

− フレームワークの利用者が入れ子にした型を表現することが可能であるとは仮定しないほうが望まし

い。 

− 異なるインタフェース上の同じ名前及び識別情報のメソッドの実装が独立していると仮定するのが望

ましい。 

− 初期化子値に基づいて自動的に実行される値型の初期化に依存しないほうが望ましい。 

13 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

− 利用者は総称型をインスタンス化し,使用できると想定してもよいが,新しい総称型や総称メソッド

を定義することを要求しないのが望ましく,また,部分的な構築総称型を扱うことを要求しないほう

が望ましい。 

フレームワークは,次のことをするのが望ましくない。 

− すなわち,新しい総称型及び総称メソッド,既存の総称メソッドの上書き,又は,いかなる方法での

部分的な構築総称性を利用者に要求しないほうが望ましい。 

この話題に関するCLSの規則は,7.2のCLS規則48を参照する。 

7.2.2 

CLS使用側 

CLS使用側とは,CLS合致のフレームワーク(ライブラリ)によって供給された機能のすべてへのアク

セスを許可するが,必ずしも,それらを作成できる必要性はないように設計された言語又はツールとする。

次はCLS使用側ツールが行うことが可能であると予想されるものの一部である。 

− 任意のCLS合致のメソッド又は委譲を呼び出すことを実現する。 

− プログラム言語でキーワードとして扱われる名前のメソッドを呼び出す機構をもっている。 

− 一つの型の中で,同じ名前及び識別情報をもつが,複数の異なるインタフェースに実装されたメソッ

ドを,区別して呼び出すことを実現する。 

− 任意のCLS合致の型のインスタンスを生成する。 

− 任意のCLS合致のフィールドを読み込み及び変更する。 

− 入れ子にした型にアクセスする 

− 任意のCLS合致の特性をアクセスする。これは,特性の取得子(getter)メソッドと設定子(setter)

メソッドとを呼び出す能力以外に,特殊な実現を要求しない。 

− 任意のCLS合致のイベントをアクセスする。これは,イベントのために定義されたメソッドを呼び出

す能力以外に,特殊な実現を要求しない。 

− 総称型及び総称メソッドを移入,インスタンス化,及び使用する。 

注記 次は,CLS使用側が提供することを考慮することが望ましい。 

− 

言語で定義された規則に基づいて,総称メソッドを一致させるための型推論 

− 

あいまい(曖昧)なキャストを共通の上位型へキャストする構文 

次は,CLS使用側ツールの機能として不必要とする。 

− 新しい型又はインタフェースの生成。 

− 静的リテラルフィールド以外のフィールド及び仮引数での初期化メタデータ(第2章参照)。使用側は,

初期化メタデータを使用することを選択できるが,しかし静的リテラルフィールド以外の何かについ

てのメタデータを無視しても問題ない。 

7.2.3 

CLS拡張側 

注記 ここから“参考情報終わり”という文を含む注記までは,参考情報であり規定ではない。 

CLS拡張側はフレームワークを使用及び拡張することをプログラマができるように設計された言語又は

ツールとする。CLS拡張側は,CLS使用側が提供する振る舞いの上位集合を提供する。すなわち,CLS使

用側に適用するものはすべて,CLS拡張側にも適用される。使用側の要件に加えて,拡張側は次のものが

可能であることが期待される。 

− すべての(封印されなかった)CLS合致の基底クラスを拡張するCLS合致の新しい型を定義する。 

− 言語でキーワードである名前をもった型を定義する目的のある機構をもっている。 

− 型に保持されたすべてのインタフェースのすべてのメソッドに独立した実装を供給する。すなわち,

background image

14 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

拡張側が同じ名前及び識別情報のすべてのインタフェースメソッドを単一のコード本体に実装するこ

とだけでは十分ではない。 

− 任意のCLS合致のインタフェースを実装する。 

− メタデータのすべての適切な要素に任意のCLS合致のカスタム属性を設定する。 

− いずれかの(封印されなかった)CLS合致の基底型を拡張して,新しい(総称でないもの)CLS合致

の型を定義する。有効な基底型には,通常の(総称でない)型及び完全構築総称型も含まれる。 

注記 次は,CLS拡張側が提供することを考慮することが望ましい。 

− 

言語で定義された規則に基づいて,総称メソッドを一致させるための型推論 

− 

曖昧なキャストを共通の上位型へキャストする構文 

拡張側は次を提供する必要はない。 

− CLS合致のインタフェースを新しく定義する。 

− 入れ子にした型を定義する。 

− 総称型及び総称メソッドを定義する。 

− 既存の仮想総称メソッドを上書きする。 

共通言語仕様は,適正に,表現力が豊かであるほどに十分に大きく,すべての言語が合理的にそれを提

供することが可能であるように十分に小さく設計される。 

注記 参考情報終わり 

CLS規則48 一つの型の中で宣言された二つ以上のCLS合致のメソッドが同じ名前をもち,かつ,あ

る特定の型のインスタンス化集合に対して,同じ仮引数及び返却値型をもつ場合,これらすべてのメソッ

ドは,それらの型のインスタンス化において意味的に同じでなければならない。 

注記  

CLS(使用側) メソッドのいずれかを選ぶことができる。 

CLS(拡張側) 使用者側と同じ。 

CLS(フレームワーク) この規則に違反するメソッドを公開してはならない。 

注記 混乱を避けるため,この標準の版における規則の削除や追加にかかわらず,CLS規則は前の版

からの時系列的な番号に従う。そして,この章に示す最初の規則は,48である。 

7.3 

CLS合致 

CLS合致に関する規則の詳細な説明は,共通の形式でなされる。例えば,次の最初の規則を参照された

い。最初の段落は規則それ自体を規定する。その後,上に記述されるような三つの異なる観点からの規則

の含意についての規定ではない記述が続く。 

CLSは言語相互運用性規則を定義する。それは“外部的に可視の”項目にだけ適用する。その言語相互

運用性のCLS単位はアセンブリである,すなわち,単一のアセンブリ内では,使用されるプログラム技法

に関して制限はない。すなわち,CLS規則が適用される項目は,その項目を定義するアセンブリの外部か

らの可視性(8.5.3参照)をもつ項目であり,“公開”,“ファミリ”又は“ファミリ又はアセンブリ”のア

クセス可能性(8.5.3.2参照)をもつ項目に限られる。 

CLS規則1 CLS規則は,定義の行われるアセンブリの外部からアクセス可能又は可視である型の部分

に適用される。 

background image

15 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

注記  

CLS(使用側) 影響はない。 

CLS(拡張側) コンパイル時にCLS合致を確認する場合,必ずアセンブリの外部に移出さ

れる情報にだけ規則を適用する。 

CLS(フレームワーク) CLS規則はアセンブリ内の内部実装に適用されない。型がCLS 合

致であるのは,すべての公開アクセス可能部分(別のアセンブリで実行するコードで使用可能

であるクラス,インタフェース,メソッド,フィールド,特性及びイベント)が次の条件の少

なくとも一つを満たす場合だけになる。 

各部分は,CLS合致の型からだけで構成される識別情報をもっている。 

各部分は,CLS合致でないものとして特に印付けされている。 

素早くコードを検証することが不可能なすべての構築要素はCLSから除外される。これによって,CLS

合致のすべての言語翻訳プログラムに対して,正当性検証可能なコードの作成を可能にする。 

7.3.1 

CLS合致のものとして印付ける項目 

CLSは,アセンブリの外部的に可視の一部に対して,それらがCLS要件に応じるかどうかを印付けする

方法を指定する(実装者が,CLS合致としてこの規格の印付けを拡張することは,奨められない。)。これ

はカスタム属性機構(9.7及び第2章参照)を用いて行われる。クラスSystem.CLSCompliantattribute

(第4章参照)は,どの型及びどの型のメンバがCLS 合致であるかを示す。さらに,それはアセンブリ

が含んでいるすべての最上位の型に対する省略時の合致水準を指定するためにアセンブリに付けることが

可能である。 

System.CLSCompliantattributeに対する構築子は,関係している項目がCLS 合致かどうか示す

真理値の実引数をとる。これは,任意の項目(アセンブリ,型又は型メンバ)がCLS 合致のものとして

明示的に印付けされることを可能にする。 

CLS合致を決定するための規則は次のとおりとする。 

− アセンブリが明示的なSystem.CLSCompliantattributeをもたない場合,それは

System.CLSCompliantattribute(false)をもつと仮定されなければならない。 

− 既定では,型は,それを囲む型(入れ子にした型のための)のCLS合致の属性を継承するか,又はそ

のアセンブリ(最上位の型のための)に付けられた値を得る。System.CLSCompliantattribute

属性の添付によってCLS合致のもの,又は,CLS合致でないもののいずれかとして,それが印付けで

きる。 

− 既定では,他のメンバ(メソッド,フィールド,特性及びイベント)は,CLS合致のそれらの型を継

承する。属性System.CLSCompliantattribute(false)の添付によってCLS合致でないものと

して,それらが印付けされることができる。 

CLS規則2 CLS合致でない型のメンバはCLS合致に印付けされてはならない。 

注記  

CLS(使用側) 上の規則を用いてCLS合致でないあらゆるメンバを無視してもよい。 

CLS(拡張側) 新たに作成されたアセンブリ,並びに公開された型及び公開されたメンバの

正確な印付けを促進するのが望ましい。CLS規則のコンパイル時適用は強く推奨される。 

CLS(フレームワーク) 正確にそれらのCLS合致に関して,公開であるメンバにすべて印

background image

16 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

付けなければならない。ここで指定された規則は要求される標示子の個数をできるだけ少なく

する目的で使用することができる(例えば,型及びメンバがすべて合致である場合に又は印付

けされる必要のあるほんの少数の例外がある場合に,全アセンブリを印付けることができる。)。 

共通型システム 

型は,値を記述し,その型のすべての値が提供しなければならない契約(8.6参照)を規定する。共通型

システム(Common Type System,以下CTSともいう。)は,関数型プログラム言語及び手続型プログラム

言語だけでなくオブジェクト指向プログラム(OOP)にも提供されるから,2種類の実体,オブジェクト

(Object)及び値(Value)を扱う。値は,整数,浮動小数点数などのための単純なビットパターンとする。

それぞれの値は型をもつ。型は,その値が占有する記憶域及びその表現におけるビットの意味を記述する。

値は,その表現において実行可能な演算ももつ。値は,Cのようなプログラム言語での対応する単純な型

を表現することを意図しているが,C++及びJava 1) といったプログラム言語の非オブジェクトを表現する

ことも意図している。 

注1) Javaは,Sun Microsystemsの商標及び登録商標である。この情報は,この規格の利用者の便宜

を図って記載するもので,この製品を推奨するものではない。 

オブジェクトは,値がもつ以上のことをもつ。各オブジェクトは,それ自体,型付けされている。すな

わち,その型は,明示的にその表現の中に含まれている。オブジェクトは,それを他のすべてのオブジェ

クトと区別する同一性(識別性)をもち,(オブジェクト又は値のいずれかが可能な)他の実体を格納する

スロットをもつ。そのスロットの内容は変化可能だが,オブジェクトの同一性は決して変化しない。 

(参考である)図1に示すとおり,オブジェクト及び値には,幾つかの種類がある。 

総称性という機能によって,型及びメソッドの一族全体をパターンを用いて定義できる。このパターン

には,総称仮引数という場所取りの仮引数が含まれる。これらの総称仮引数は,実際に要求されるその一

族のメンバをインスタンス化するために,必要に応じて,指定された型によって置き換えられる。総称性

の設計は,次の目的を満たす。 

− 直交性。可能な場合,既存のCLIの型が出現可能なあらゆる文脈で,総称型は出現できる。 

− 言語の独立性。元となる言語についていかなる仮定も行わない。しかし,CLI総称性は,可能な限り

多くの言語の既存の総称性らしい機能を提供しようとする。さらに,CLI総称性の設計は,現在総称

性をもたない言語の新たな拡張を許す。 

− 実装の独立性。CLIの実装は,その場その場に応じて表現及びコードを特殊化するか,又はすべての

表現及びコードを共有できる。これを達成するために,おそらく,値のボックス化及びボックス化解

除を行うことがある。 

− 実装の効率性。総称性の実行効率は,総称性を模擬するObjectを使うよりも悪いことはない。よい

実装は,参照型のインスタンス化についてキャストを避け,値型のインスタンス化について特殊化し

たコードを生成するから,ずっと効率的にできる。 

− 定義における静的検査可能性。総称型定義は,そのインスタンス化とは独立に,妥当性検証及び正当

性検証を行うことができる。そこで,総称型は,静的に正当性検証可能であって,そのメソッドは,

すべての妥当なインスタンス化に対してJITコンパイルを保証できる。 

− 総称仮引数に関する一様な振る舞い。一般に,仮引数化された型及び総称メソッドの振る舞いは,す

べての型のインスタンス化において“同じ”となる。 

加えて,CLIは,次の特徴をもつ,共変及び反変な総称仮引数を提供する。 

background image

17 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

− (純粋に静的な検査に基づいた)型安全。 

− 単純性。特に,(共変及び反変の)可変性は,(クラス又は値型でない)総称インタフェース及び総称

委譲にだけ許可される。 

− 可変性を提供したくない言語は,その機能を無視し,すべての総称型を可変ではないとして取り扱う

ことができる。 

− Eiffelなどの言語で使用されるより複雑な共変性方式の実装を可能にする。 

図1に型システムを示す。 

注記 図1は,参考とする。 

注記 管理下ポインタは,ヒープ領域を指し示すかもしれない。 

図1−型システム 

8.1 

オブジェクト指向プログラムとの関係 

注記 この細分箇条は参考情報であり規定ではない。 

型は,値指向プログラムの世界で,データ表現を意味するためによく使用される。オブジェクト指向の

世界では,表現よりむしろ振る舞いを参照するために使用する。CTSでは,型は,これら両方を意味する

ために使用する。二つの実体は,それらが互換性のある表現及び互換性のある振る舞いをもつ場合かつそ

の場合に限り,互換性のある型をもつ。このように,CTSでは,一つの型が基底型から派生する場合,そ

の派生型のインスタンスは,その表現及び振る舞いの両方とも(基底型のインスタンスと)互換性がある

から,基底型のインスタンスに対して置き換えることができる。 

幾つかのオブジェクト指向プログラム言語(以下,OOP言語ともいう。)とは異なり,CTSでは,基本

的に異なる表現をもつ二つのオブジェクトは,異なる型をもつ。OOP言語の中には,異なる型の概念を使

用するものがある。それらは,二つのオブジェクトがメッセージの同じ集合に対して同じ方法で応答する

18 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

場合に同じ型をもつと考える。CTSでは,この概念は,オブジェクトが同じインタフェースをもつとして

取り込まれている。 

同様に,(例えばSmalltalkといった)幾つかのOOP言語は,メッセージの受渡しを計算の基本モデルと

考える。CTSでは,これは,仮想メソッド呼出し(8.4.4参照)に対応する。この場合,仮想メソッドの識

別情報がメッセージの役割をする。 

CTSそれ自体は,“型のないプログラム”の概念を直接には取り込んでいない。すなわち,オブジェク

トの型を知ることなしに非静的メソッドを呼び出す方法はない。それにもかかわらず,自己反映パッケー

ジ(第4章参照)が実装されている場合には,それが提供する能力に基づいて,型のないプログラムを実

装できる。 

8.2 

値及び型 

型は,値を記述する。型によって記述されるあらゆる値を,その型のインスタンスと呼ぶ。値のあらゆ

る使用,すなわち,それを格納し,受け渡し,操作するには,型が要求される。これは,特に,すべての

変数,実引数,評価スタックの格納域及びメソッド結果に適用される。型は,可能な値及びその型の値が

提供する可能な演算を定義する。すべての演算子及び関数は,アクセスされる値又は使用される値のそれ

ぞれについて期待される型をもつ。 

すべての値は,その型の特性を十分に記述する厳密な型をもつ。 

すべての値は,その厳密な型のインスタンスとするが,同様に他の型のインスタンスになることもでき

る。特に,値が別の型から継承された型のインスタンスである場合,その値は,その別の型のインスタン

スにもなる。 

8.2.1 

値型及び参照型 

型には,値型(value type)及び参照型(reference type)の2種類がある。 

− 値型 値型によって記述される値は,自己充足している。すなわち,それぞれは,他の値を参照する

ことなく理解できる。 

− 参照型 参照型によって記述される値は,他の値の格納域を表示する。参照型には,次の4種類があ

る。 

− オブジェクト型は,自己記述的な値の参照型とする(8.2.3参照)。幾つかのオブジェクト型(例え

ば,抽象クラスなど)は,値の部分的な記述だけになっている。 

− インタフェース型は,常に,値の部分的な記述であって,多くのオブジェクト型によって使用され

る可能性がある。 

− ポインタ型は,その表現が格納域の計算機アドレスになっている値のコンパイル時の記述とする。 

− 組込み参照型。 

8.2.2 

組込みの値型及び参照型 

表1のデータ型は,CTSの重要な部分であって,仮想実行システム(Virtual Execution System,VES)が

直接に提供する。それらは,永続的メタデータの中で特殊な符号化をもつ。 

background image

19 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

表1−特殊な符号化 

CILアセンブラにおける名前

(第2章参照) 

CLS型かどうか 

クラスライブラリにおける名前

(第4章参照) 

説明 

bool 

Yes 

System.Boolean 

true又はfalseの値 

char 

Yes 

System.Char 

Unicodeの16ビットの文字 

object 

Yes 

System.Object 

オブジェクト又はボックス化
された値型 

string 

Yes 

System.String 

Unicode文字列 

float32 

Yes 

System.Single 

IEC 60559:1989の32ビット浮
動小数点数 

float64 

Yes 

System.Double 

IEC 60559:1989の64ビット浮
動小数点数 

int8 

No 

System.SByte 

符号付き8ビット整数 

int16 

Yes 

System.Int16 

符号付き16ビット整数 

int32 

Yes 

System.Int32 

符号付き32ビット整数 

int64 

Yes 

System.Int64 

符号付き64ビット整数 

native int 

Yes 

System.IntPtr  

符号付き整数,プラットフォー
ム固有のサイズ 

native unsigned int 

No 

System.UIntPtr 

符号なし整数,プラットフォー
ム固有のサイズ 

typedref 

No 

System.TypedReference 

厳密な型の付いたポインタ 

unsigned int8 

Yes 

System.Byte 

符号なし8ビット整数 

unsigned int16 

No 

System.UInt16 

符号なし16ビット整数 

unsigned int32 

No 

System.UInt32 

符号なし32ビット整数 

unsigned int64 

No 

System.UInt64 

符号なし64ビット整数 

注記 bool及びcharは,図1の分類では整数型になっている。 

8.2.3 

クラス,インタフェース及びオブジェクト 

型は,その値の表現及びその値で定義された演算をあいまい(曖昧)性なく定義する場合に,値を十分

に記述するという。 

値型について,その表現を定義するとは,その値の表現を構成するビットの列を記述することをいう。

参照型について,その表現を定義するとは,その値の表現を構成するビットの列及びその格納域を記述す

ることをいう。 

メソッドは,厳密な型の値で実行できる演算を記述する。厳密な型の値で許される演算の集合を定義す

るとは,それぞれの演算のための名前付きメソッドを規定することをいう。 

型の中には,例えば,インタフェース型のように,部分的な記述だけのものもある。インタフェース型

は,演算の部分集合を記述するが表現は記述せず,いかなる値の厳密な型にもなれない。その結果,値は

ただ一つの厳密な型をもつが,同様に多くの他の型の値となることもできる。さらに,厳密な型は,その

値を十分に記述するから,その厳密な型の値がもつことができる他の型のすべても十分に規定する。 

すべての値が一つの厳密な型をもつことは正しいが,その値の表現を調べることによってその厳密な型

を常に決定できるというわけではない。特に,値型の値の厳密な型を決定することは不可能である。例え

ば,二つの組込みの値型である,32ビットの符号付き整数及び符号なし整数を考える。それぞれの型は,

それぞれの値の十分な規定になっているが,すなわち,厳密な型であるが,一つの値の特定の32ビット列

からその厳密な型がいずれであるのかを導出する方法はない。 

20 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

オブジェクトという値については,その値から厳密な型を常に決定できる。オブジェクトの厳密な型は,

オブジェクト型という。オブジェクトは,参照型の値だが,すべての参照型がオブジェクトを記述するわ

けではない。32ビット整数へのポインタである値を考える。この型は,参照型である。ポインタのビット

の並びを調べることによってその値の厳密な型を発見する方法はない。したがって,これはオブジェクト

ではない。組込みのCTS参照型 System.String(第4章参照)を考える。この型の値の厳密な型は,

その値を調べることによって常に決定できる。したがって,型System.Stringの値はオブジェクトであ

って,System.Stringはオブジェクト型になる。 

8.2.4 

値のボックス化及びボックス化解除 

すべての値型について,CTSは,ボックス化型という対応する参照型を定義する。この逆は正しくない。

すなわち,参照型は,一般には,対応する値型をもたない。ボックス化型の値(ボックス化値)の表現は,

その値型の値が格納できる格納域とする。ボックス化型はオブジェクト型であって,ボックス化値はオブ

ジェクトになる。 

ボックス型は,名前によって直接には参照できない。その結果,いかなるフィールドにも局所変数にも

ボックス化型を与えることはできない。ボックス化列挙値型に最も近い名前付き基礎クラスは,

System.Enumとする。それ以外のすべての値型に対しては,System.ValueTypeとする。

System.ValueTypeの型をもつフィールドは,null値又はボックス化値型のインスタンスだけを含むこ

とができる。System.Enumの型をもつ局所変数は,null値又はボックス化列挙型のインスタンスだけを

含むことができる。 

すべての値型は,ボックス化という演算をもつ。値型の値をボックス化すると,そのボックス化値が生

成される。すなわち,その値は,元の値のビット単位のコピーを含む対応するボックス化型の値になる。

値型が,値型System.Nullable<T>のインスタンス化として定義されるヌル許容型である場合,(ボッ

クス化の)結果は,そのHasValue特性に依存して,すなわち,その値の偽又は真に依存して,それぞれ,

ヌル参照又は型TのValue特性のビット単位のコピーになる。すべてのボックス化型は,ボックス化解

除という演算をもつ。ボックス化解除を行うと,その元の値のビット表現への,管理されたポインタを生

じる。 

ボックス化命令は,単に値型以上のものに適用できる。そのような型を,ボックス化可能型という。型

は,次の一つの場合にボックス化可能とする。 

− CIL評価スタックを指し示すことができるフィールドを含まない(総称値型のインスタンス化を含む)

値型。 

注記 この根拠は次のとおりである。そのようなフィールドを含む値型はボックス化できない。こ

れは,そうでないと,これらの埋め込まれたポインタ,例えば,

System.RuntimeArgumentHandle,System.TypedReferenceなどが指し示すCIL評

価スタックの中の項目よりも長続きすることが可能になってしまう。それらのポインタを含

む値型を,非形式的には,“byref風”値型という。 

− (クラス,配列,委譲及び総称クラスのインスタンス化を含む)参照型。 

− 管理外ポインタ型。 

− (総称型定義又は総称メソッド定義に対する)総称仮引数。 

注記 総称実引数のボックス化及びボックス化解除は,CLI実装に性能の負荷を課す。

Constrained接頭辞は,値型のボックス化を避けることによって,値型が定義するメソッ

ドへの仮想ディスパッチの最中の性能を改善できる。 

background image

21 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

型System.Voidは,ボックス化不可とする。 

インタフェース及び継承は,参照型だけに定義される。値型の定義(8.9.7参照)は,その値型が実装し

なければならないインタフェース及びその値型を継承するクラス(System.ValueType又は

System.Enum)の両方を規定できるが,これらのインタフェース及びクラスは,ボックス化値に対して

だけ適用される。 

CLS規則3 ボックス化値は,CLS合致ではない。 

注記 ボックス化型の代わりに,必要に応じて,System.Object,System.ValueType又は

System.Enumを使用する。 

CLS(使用側) ボックス化値の型を移入する必要はない。 

CLS(拡張側) ボックス化値の型を定義又は使用するための構文を提供する必要はない。 

CLS(フレームワーク) 公開する部分でボックス化値の型を用いてはならない。 

8.2.5 

値の同一性及び等価性 

値のすべての対で定義される二つの2項演算子,同一性演算子及び等価(性)演算子が存在する。これ

らは真理値の結果を返す。これらの演算は,数学的には,両方とも同値演算子になる。すなわち,次が成

立する。 

− 反射律 a op a が成り立つ。 

− 対称律 a op b が成り立つのは,b op a が成り立つ場合かつその場合に限る。 

− 推移律 a op b が成立し,b op c が成立する場合,a op c が成立する。 

さらに,同一性は常に等価性を意味するが,逆はいえない。 

これらの演算の間の違いを理解するのに,型がSystem.Stringである三つの変数A,B及びCを考え

る(次の図参照)。ここで,矢印は“…への参照である”ことを意図している。 

変数の値は,文字の列の格納域が同じ場合,同一になる。すなわち,実際,記憶域上にはただ一つの文

字列だけが存在する。変数の中に格納された値は,文字の列が同じ場合,等価になる。そこで,変数A及

びBの値は同一になり,変数A及びCの値,並びに,変数B及びCの値は,同一ではないが,A,B及

びCの三つすべての値は等価になる。 

8.2.5.1 

同一性 

同一性演算子は,CTSによって次のとおりに定義される。 

− 値が,異なる厳密な型をもつ場合,それらは同一ではない。 

− 値が,同じ厳密な型をもつ場合であって,それらの厳密な型が値型である場合,値のビット列が同じ

場合かつその場合に限り,それらの値は,同一とする。 

− 値が,同じ厳密な型をもつ場合であって,それらの厳密な型が参照型である場合,値の格納域が同じ

場合かつその場合に限り,それらの値は,同一とする。 

同一性は,System.Object上にReferenceEqualsメソッドを通じて実装される。 

22 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

8.2.5.2 

等価性 

値型に対して,等価演算子は,その厳密な型の定義の一部になる。等価性の定義は,次の規則に従うの

が望ましい。 

− 等価演算子は,先に定義した同値演算子であることが望ましい。 

− 同一性は,先に示したとおり,等価性を示唆することが望ましい。 

− いずれか(又は両方)の演算対象がボックス化値である場合,等価性は,次によって計算されること

が望ましい。 

− 最初に,ボックス化された演算対象のボックス化を解除する。 

− 次に,結果として生じた値に等価性の通常の規則を適用する。 

等価性は,System.Object上にEqualsメソッドを通じて実装される。 

注記 二つの浮動小数点数NaNは,IEC 60559:1989によって,常に等価ではないとして比較されると

定義されているが,System.Object.Equalsについての契約は,その上書きメソッドが同値

演算子に対する要件を満足しなければならないことを要求する。その結果, 

System.Double.Equals及びSystem.Single.Equalsは,二つのNaNを比較したとき,

Trueを返す。その一方で,等価演算子は,IEC 60559:1989が要求するとおり,NaNの比較で

Falseを返す。 

8.3 

格納域 

値は,ある格納域に格納される。一つの格納域は,一度にただ一つの値を保持できる。すべての格納域

は型付けされている。格納域の型は,その格納域に格納される値が満たさなければならない要件を具現化

している。格納域の例としては,局所変数及び仮引数がある。 

更に重要なことだが,格納域の型は,その格納域からロードされるあらゆる値の使用法についての制限

を規定する。例えば,一つの格納域は,潜在的に多くの厳密な型の値を,それらの値すべてが格納域の型

と互換性があるように代入される限りは,保持できる。一つの格納域からロードされるすべての値は,そ

れらがその格納域の型をもつものとして,取り扱われる。たとえ,格納域に格納された値の厳密な型が付

加的な演算を可能にしていたとしても,その格納域の型に対して有効な演算だけを呼び出すことができる。 

8.3.1 

代入互換な格納域 

値は,その値の型の一つが格納域の型と代入互換な場合に限り,その格納域に格納できる。型は,常に

それ自体と代入互換とする。代入互換性はコンパイル時に決定されることが多く,その場合には,実行時

の試験は不要になる。代入互換性は,8.7で詳細に示す。 

8.3.2 

強制型変換 

場合によっては,格納域と代入互換ではない型の値をとり,そして,その値を代入互換のある型に変換

することが望ましいことがある。強制型変換は,特定の型の値及び望まれる型をとり,元の値と同等な意

味をもつ望まれる型の値を生成しようとする。強制型変換は,型の変更だけでなく表現の変更を生じる可

能性がある。だから,強制型変換は,必ずしもオブジェクトの同一性を保存しない。 

強制型変換には2種類ある。それらは,決して情報を失わない拡大及び情報を失うかもしれない縮小と

する。32ビット符号付き整数の値を64ビット符号付き整数の値に強制型変換するのは,拡大強制型変換

の例である。この逆,すなわち,64ビット符号付き整数の値を32ビット符号付き整数の値に強制型変換

するのは,縮小強制型変換の例である。プログラム言語は,拡張強制型変換を暗黙的変換として実装する

ことが多い。一方,縮小強制型変換は,通常,明示的変換として実装される。 

拡張強制型変換の中には,直接に,組込み型上のVES演算で構築されるものがある(12.1参照)。他の

23 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

すべての強制型変換は,明示的に要求されなければならない。組込み型について,CTSは,実行時検査な

しの拡大強制型変換及び実行時検査付きの縮小強制型変換を実行するための演算を提供する。 

8.3.3 

キャスト 

値は二つ以上の型をもちうるから,値を使用するときには,その値のどの型を用いているかを明確に識

別する必要がある。値は型付けされた格納域から読み込まれるから,使用される値の型は,その値が読み

込まれた格納域の型とする。異なる型を使用するのが望ましい場合,その値は,他の型の一つにキャスト

される。キャストは,通常はコンパイル時の演算だが,コンパイラが値のターゲット型を静的に知らない

場合,実行時のキャスト検査が行われる。強制型変換とは異なり,キャストは,オブジェクトの実際の型

を変更しないしその表現も変更しない。キャストは,オブジェクトの同一性を保存する。 

例えば,特定のインタフェースの値を保持しながら,型付けされた格納域から読み出された値をキャス

トするとき,実行時検査を必要とするかもしれない。インタフェースは値の不完全な記述なので,その値

を異なるインタフェース型にキャストすると,通常は,実行時キャスト検査が生じる。 

8.4 

型メンバ 

先に示したとおり,型は,許可される値及びその型の値が提供する許可される演算を定義する。型の許

可される値が部分構造をもつ場合,その部分構造は,その型のフィールド又は配列要素を通じて記述され

る。型の一部である演算が存在する場合,それらの演算は,その型のメソッドを通じて記述される。フィ

ールド,配列要素及びメソッドは,型のメンバという。特性及びイベントも型のメンバとする。 

8.4.1 

フィールド,配列要素及び値 

値の表現は,(組込み型である場合を除いて)部分値に分割できる。この部分値は,名前をもつか,又は

添字指定式によってアクセスされる。名前をもつ場合は,フィールドという。添字指定式を使う場合は,

配列要素という。配列要素から構成される値を記述する型は,配列型とする。フィールドから構成される

値を記述する型は,複合型とする。一つの値は,フィールド及び配列要素の両方を含むことはできない。

ただし,複合型のフィールドが配列型であったり,配列要素が複合型であったりすることができる。 

配列要素及びフィールドは型付けされており,それらの型は決して変化しない。一つの配列中の要素は,

すべて同じ型をもたなければならない。複合型のそれぞれのフィールドは,異なる型をもつことができる。 

8.4.2 

メソッド 

型は,演算を,その型又はその型の各インスタンスと関連付けることができる。それらの演算をメソッ

ドという。メソッドは,名前をもち,その実引数のすべて及び存在する場合にはその返却値に対して許さ

れる型を規定する識別情報(8.6.1参照)をもつ。 

型の特定のインスタンスにではなく,型それ自体だけと関連付けられたメソッドを静的メソッド(8.4.3

参照)という。 

型のインスタンスに関連付けられたメソッドは,インスタンスメソッド又は仮想メソッド(8.4.4参照)

のいずれかとする。インスタンスメソッド及び仮想メソッドが呼び出されるとき,それらは,この呼出し

が演算を行う(this 又はthis pointerとして知られる)インスタンスに渡される。 

インスタンスメソッドと仮想メソッドとの基本的な違いは,その実装の格納域の与えられる方法にある。

インスタンスメソッドは,クラス及びそのクラス内のそのインスタンスメソッドを指定することによって

呼び出される。thisとして渡されるオブジェクトは,null(インスタンスが指定されていないことを示す特

殊な値。ヌル,ナルなどともいう。)又はそのメソッドを定義するクラスから継承(8.9.8参照)される型

のインスタンスとすることができる。仮想メソッドも,これと同じ方法で呼び出すことができる。例えば,

仮想メソッドの実装が基底クラスが提供する実装を呼び出したい場合に,これが発生する。CTSは,仮想

background image

24 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

クラスの本体の内部でthisをnullとすることを許している。 

注記 この根拠は次のとおりである。仮想メソッドを非仮想呼出しで呼び出せるようにしたから,

“call super”命令が不要になり,仮想メソッドと非仮想メソッドとの間で版の変更が可能にな

る。これは,CIL生成器がnullのthisポインタを呼び出されたメソッドに伝ぱ(播)したくな

い場合には,CIL生成器に,ヌルポインタのための明示的な試験を要求する。 

仮想メソッド又はインスタンスメソッドは,仮想呼出しという異なる機構によって呼び出すこともでき

る。仮想メソッドを定義する型から継承されるあらゆる型は,そのメソッドのその型それ自体の実装を提

供できる。これは,上書きとして知られている(8.10.4参照)。どの実装が呼び出されるかを決定するのに

使用されるのは,(実行時に決定される)オブジェクトの厳密な型とする。 

8.4.3 

静的フィールド及び静的メソッド 

型は,その型の特定の値ではなくてその型に関連した格納域を宣言できる。このような格納域を,その

型の静的フィールドという。すなわち,静的フィールドは,その型のすべての値が共有する格納域を宣言

する。非静的(インスタンス)フィールドと同様に,静的フィールドは型付けされており,その型は決し

て変化しない。静的フィールドは,常に一つのアプリケーションドメイン(12.5参照)に制限されている

が,スレッドごとに割り当てることもできる。 

同様に,型は,その型の値ではなくその型に関連するメソッドも宣言できる。このようなメソッドをそ

の型の静的メソッドという。静的メソッドの呼出しは,その静的メソッドが演算を行う関連する値をもた

ないから,静的メソッド内に利用可能なthisポインタは存在しない。 

8.4.4 

仮想メソッド 

オブジェクト型は,そのメソッドを仮想として宣言できる。他のメソッドとは異なり,その型を実装す

る厳密な型が,仮想メソッドのその型自体の実装を提供できる。仮想メソッドは,実装を選択するための,

静的な型,メソッド名及び仮引数の型を用いる通常のメソッド呼出し機構を通じて呼び出すことができる。

この場合,thisポインタはnullにできる。しかし,更に,仮想メソッドは,ある特殊な機構,仮想呼出し

によって呼び出すことができる。この場合,メソッドの実装は,コンパイル時に静的に知られる型ではな

く,その仮想呼出しを行うのに使用されたインスタンスの動的に検知された型に基づいて選択される。仮

想メソッドは,final(8.10.2参照)と印付けできる。 

8.5 

名前付け 

名前は,型システムの実体に与えられ,その結果として,実体は,その型システムの他の部分によって

又はその型の実装によって参照できるようになる。型,フィールド,メソッド,特性及びイベントは,名

前をもつ。型システムでは,値,局所変数及び仮引数は名前をもたない。型システムの実体は,一つの名

前を与えられる。例えば,一つの型にはただ一つの名前だけが存在する。 

8.5.1 

妥当な名前 

すべての名前の比較は,バイトごとに(すなわち,大文字と小文字とを区別し,ロケールに依存せず,

符号位置の比較としても知られている方法で)行われる。名前が,組込みのVES提供機能(例えば,クラ

ス初期化メソッドなど)にアクセスするために使用される場合,(その名前が)予約された名前のあらゆる

集合の中で構築されないように,常に,(その名前の)定義に関して付随する指示が存在する。 

CLS規則4 アセンブリは,識別子の開始文字及び継続文字の集合を規定するUnicode Standard 3.0の技

術文書15の附属書7に従わなければならない。この文書は, 

http://www.unicode.org/unicode/reports/tr15/tr15-18.htmlで入手できる。識別子は,Unicode正規化形式C

background image

25 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

(Unicode Normalization Form C)が定義する正規形式でなければならない。CLSの目的に対しては,二つ

の識別子は,(Unicodeのロケールを意識しない1対1小文字対応付けが規定するとおりに)それら識別子

を小文字に対応付けたものが同じ場合に同じとする。すなわち,二つの識別子がCLSにおいて異なってい

ると考えられる場合,それらは,単に大文字と小文字とが異なっている以上に異なっている。しかし,継

承された定義を上書きするときに,CLIは,元の宣言の正確な符号化が使用されることを要求する。 

注記  

CLS(使用側) CLS規則4に違反する型を使う必要はない。しかし,使用側それ自体のキー

ワードの一つを名前として使用する名前付けられた項目にアクセス可能な機構をもたなければ

ならない。 

CLS(拡張側) CLS規則4に違反する型を生成する必要はない。しかし,これらの規則に従

い,拡張側の言語におけるキーワードと同じ新しい名前を定義する機構を提供しなければなら

ない。 

CLS(フレームワーク) CLS規則4に違反する型を移出してはならない。各種のプログラム

言語で共通的にキーワードとして使用される名前の使用は避けることが望ましい(第6章,附

属書D参照)。 

8.5.2 

アセンブリ及び有効範囲付け 

一般に,名前は一意ではない。名前は,有効範囲というグループ化されたものに集められる。一つの有

効範囲内では,一つの名前は,それが参照する実体が異なる種類(メソッド,フィールド,入れ子になっ

た型,特性及びイベント)であるか,又は異なる識別情報をもつ限り,複数の実体を参照できる。 

CLS規則5 CLS合致の有効範囲で導入されるすべての名前は,それら名前が同一であって多重定義に

よって解決される場合を除いて,種類とは独立に異なっていなければならない。すなわち,CTSは,一つ

の型がメソッド及びフィールドに対して同じ名前を使用することを許すが,CLSは許さない。 

CLS規則6 CTSでは異なる識別情報は区別可能だが,CLSでは,フィールド及び入れ子になった型は,

識別子の比較だけによって異なっていなければならない。(識別子の比較によって)同じ名前をもつメソッ

ド,特性及びイベントは,単に返却値の型だけ以外によって異なっていなければならない。ただし,CLS

規則39で規定した場合を除く。 

注記  

CLS(使用側) CLS合致ではないと印付けられたあらゆるメンバを無視した後で,これらの

規則に違反する型を使用する必要はない。 

CLS(拡張側) これら規則に違反する型を定義するための構文を提供する必要はない。 

CLS(フレームワーク) 型内の規則を破る項目を,残りのメンバが互いに矛盾しないように

CLS合致でないと印付けしていない場合,型がこれらの規則に違反するならば,それらの型を

CLS合致と印付けしてはならない。 

名前付けされた実体は,ただ一つの有効範囲の中でその名前をもつ。そこで,名前付けされた実体を識

別するためには,有効範囲及び名前の両方が提供される必要がある。有効範囲は,名前を限定する。型は,

その型の中の名前に対して一つの有効範囲を提供する。その結果,型は,その型の中の名前を限定する。

例えば,xと名前を付けられたフィールドをもつ複合型Pointを考える。名前“フィールドx”は,それ

自体では,名前付けられたフィールドを一意には識別しない。しかし,限定名“型Pointの中のフィール

background image

26 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

ドx”は一意に識別する。 

型は名前をもつから,型の名前も有効範囲にグループ化される。型を十分に識別するためには,その型

名は,それを含む有効範囲によって限定されていなければならない。型名は,その型の実装を含むアセン

ブリによって有効範囲付けされる。アセンブリは,ロード可能なコードモジュールと,機能の単位を一緒

に実装している他の資源とから構成された集合とする。型名は,その型を実装するアセンブリのアセンブ

リ有効範囲の中にあるという。アセンブリそれ自体は,CTS名前階層の基礎となる名前をもつ。 

型定義は,次を行う。 

− 定義している型に対する名前,すなわち,型名を定義し,その名前が見いだされる有効範囲を規定す

る。 

− メンバの異なる種類(フィールド,メソッド,イベント及び特性)の名前を束縛するメンバ有効範囲

を定義する。メンバ名,メンバ種類,メンバ識別情報の組は,型のメンバ有効範囲内で一意とする。 

− 暗黙的に,型を,その型定義を含むアセンブリのアセンブリ有効範囲に割り当てる。 

CTSは,既存の型に対して代替の名前を与える(列挙型としても知られる)enumを提供する。識別情

報を対応付けるために,enumは,それの基礎となる型と同じであってはならない。しかし,enumのイン

スタンスは,基礎となる型と互換性のある代入が可能でなければならず,逆もいえなければならない。す

なわち,キャスト(8.3.3参照)も強制型変換(8.3.2参照)もenumからその基礎となる型への変換で要求

されず,基礎となる型からenumへの変換でも要求されない。enumは,次のとおりに,本当の型よりも

注意深く制限されている。 

− enumは,ただ一つのインスタンスフィールドをもち,そのフィールドの型は,その列挙の基礎とな

る型を定義する。 

− enumは,それ自体のメソッドをもってはならない。 

− enumは,System.Enum(第4章参照)から派生しなければならない。 

− enumは,それ自体のインスタンスを実装してはならない。 

− enumは,それ自体の特性又はイベントをもってはならない。 

− enumは,そのフィールドがリテラルでない限り,静的なフィールドをもってはならない(8.6.1.2参

照)。 

基礎となる型は,組込みの整数型でなければならない。enumは,System.Enumから派生していなけれ

ばならない。その結果,値型になる。すべての値型と同様に,それは封印されなければならない(8.9.9参

照)。 

CLS規則7 enumの基礎となる型は,組込みのCLS整数型でなければならない。フィールドの名前は,

“value̲̲”でなければならず,そのフィールドは,RTSpecialNameと印付けされなければならない。 

CLS規則8 System.FlagsAttribute(第4章参照)カスタム属性が存在する又は存在しないによ

って示される二つの異なる種類のenumが存在する。一つは,名前付き整数値を表現し,もう一つは,名

前付きでない値を生成するために結合可能な名前付きビットフラグを表現する。enumの値は,指定され

た値に制限されない。 

CLS規則9 enumのリテラル静的フィールド(8.6.1参照)は,enumそれ自体の型をもたなければなら

ない。 

注記  

CLS(使用側) これらの規則に従うenumの定義を受け入れなければならない。しかし,フ

background image

27 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

ラグを名前付き値と区別する必要はない。 

CLS(拡張側) 使用側と同じ。拡張側の言語は,enumの編集を可能にすることが望まれる

が,必す(須)ではない。 

CLS(フレームワーク) これらの規則に違反するenumを開示してはならないし,(enum

が名前付き値であっても)enumが指定された値だけをもつと仮定してはならない。 

8.5.3 

可視性,アクセス可能性及びセキュリティ 

有効範囲の中の名前付き実体を参照するためには,有効範囲及びその有効範囲の中の名前の両方が,可

視でなければならない(8.5.3.1参照)。可視性は,参照を含む実体(参照元)と参照される名前を含む実

体との間の関係によって決定される。次の擬似コードを考える。 

class A 

{ int32 IntInsideA; 

class B inherits from A 

{ method X(int32, int32)  

  { IntInsideA := 15; 

  } 

クラスAの中のIntInsideAフィールドへの参照を考える。 

− クラスBはそのフィールドを参照するメソッドをもつから,クラスBを参照元と呼ぶ。 

− クラスAの中のIntInsideAを,参照される実体と呼ぶ。 

参照元が,参照される実体にアクセス可能かどうか,を決定するために答える必要がある二つの基本的

な問題が存在する。一つは,参照される実体の名前が参照元に対して可視かどうかである。可視である場

合,参照される実体がアクセス可能(8.5.3.2参照)かどうか,すなわち,参照元がアクセス可能権限をも

っているかどうか,という異なる問題がある。 

型のメンバへのアクセスは,次の三つの条件すべてが満たされる場合だけに許可される。 

− 型が可視であって入れ子になった型である場合は,アクセス可能になっている。 

− メンバがアクセス可能になっている。 

− すべての意味のあるセキュリティ要求(8.5.3.3参照)が満たされている。 

インスタンス化された総称型は,その総称型それ自体と,その構成部分(総称型定義及び総称実引数)

のそれぞれとが可視である場合かつその場合に限り,あるアセンブリから可視とする。例えば,Listがア

センブリAから移出されており(すなわち,“public”と宣言されており),MyClassがアセンブリBで

定義されているが移出されていない場合,List<MyClass>は,アセンブリB内からだけ可視となる。 

インスタンス化された総称型のメンバのアクセス可能性は,インスタンス化には依存しない。 

その結果,メンバC<T1, … Tn>.mへのアクセスは,次の条件を満足する場合に許される。 

− C<T1, ... Tn>が可視になっている。 

− 総称型C内のメンバm(すなわち,C.m)が,アクセス可能になっている。 

− セキュリティ許可が,認められている。 

8.5.3.1 

型の可視性 

メンバの名前ではなく型の名前だけが,制御された可視性をもつ。型名は,次の三つの分類の一つに所

28 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

属する。 

− 型名が定義されているアセンブリから移出されている。型がアセンブリから移出可能と印付けできて

も,その型名が使用可能かどうかを決定するのはアセンブリの構成とする。 

− 型名が定義されているアセンブリの外部には移出されていない。 

− 他の型の内部に入れ子になっている。この場合,入れ子になっている型それ自体は,それを内部に入

れ子にしている型(その囲み込む型)の可視性をもつ(8.5.3.4参照)。 

最上位の名前付きの型は,それが公開の可視性をもつ場合かつその場合に限り,移出されている。型定

義子が生成する型は,それが移出されている型から作られる場合かつその場合に限り,移出されている。 

型定義子が生成する型は,それが生成されたすべての型が可視である場合に,可視となる。 

8.5.3.2 

メンバ及び入れ子型のアクセス可能性 

型は,そのメンバすべてを有効範囲付けし,更に,そのメンバにアクセス可能性規則を指定する。特に

注意を促さない場合には,アクセス可能性は,参照されているメンバの型の静的な可視性,並びに参照を

行っている型及びアセンブリだけに基づいて決定される。CTSは,アクセス可能性のために七つの異なる

規則を提供する。 

− コンパイラ制御(compiler-controlled) 参照ではなく定義の使用を通じてだけ,アクセス可能(権限が

ある)とする。その結果,一つのコンパイル単位内からコンパイラの制御下だけでアクセス可能にな

る。 

− 私的(private) メンバを定義しているその型(厳密な型)の実装の中にある参照元に対してだけ,ア

クセス可能(権限がある)とする。すなわち,それらの参照元だけがアクセスできる。 

− ファミリ(family) 同じ型,すなわち,厳密な型及びそれから継承される型のすべてを提供する参照

元に対して,アクセス可能(権限がある)とする。正当性検証可能コード(8.8参照)に対しては,実

行時検査を要求できるという付加的な要件がある。その実行時検査は,参照は,厳密な型が参照元の

厳密な型である項目を通じて行われなければならないという検査とする。すなわち,メンバがアクセ

スされている項目は,そのアクセスを実行している型から継承されなければならない。 

− アセンブリ(assembly) 型の実装を含む同じアセンブリの中にある参照元に対してだけ,アクセス可

能(権限がある)とする。 

− ファミリ及びアセンブリ(family-and-assembly) ファミリアクセス及びアセンブリアクセスの両方に

限定される参照元に対してだけ,アクセス可能(権限がある)とする。 

− ファミリ又はアセンブリ(family-or-assembly) ファミリアクセス又はアセンブリアクセスのいずれか

に限定される参照元に対してだけ,アクセス可能(権限がある)とする。 

− 公開(public) すべての参照元に対して,アクセス可能(権限がある)とする。 

メンバ又は入れ子になった型は,それが,公開,ファミリ又はアセンブリ,ファミリといったアクセス

可能性をもち,(メンバである場合は)その定義する型又は(入れ子になった型である場合は)その囲む型

が移出されている場合及びその場合に限り,移出されている。 

型定義子のアクセス可能性は,それが生成された型のアクセス可能性と同じとする。 

一般に,型のメンバは,それに割り当てられるこれらのアクセス可能性規則のいずれか一つをもつこと

ができる。しかし,次の三つの例外がある。 

1) インタフェースによって定義される(入れ子になった型ではなく)メンバは,公開でなければなら

ない。 

2) 型が,継承された定義を上書きする仮想メソッドを定義している場合,そのアクセス可能性は,二

background image

29 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

つの定義において同一になっていなければならないか,上書きする定義が元の定義よりも広いアク

セスを許可していなければならない。例えば,アセンブリ仮想(assembly virtual)メソッドを公開

仮想(public virtual)な新しい実装で上書きすることは可能だが,ファミリ仮想(family virtual)な

実装で上書きはできない。他のアセンブリから派生した定義を上書きする場合,基底定義がファミ

リ又はアセンブリ(family-or-assembly)アクセスをもち,上書きがファミリ(family)アクセスだけ

をもつならば,アクセスを制限しているとは考えない。 

3) 入れ子になった型によって定義されるメンバ,又は入れ子になった型によって囲まれる入れ子にな

った型は,(メンバである場合には)それを定義する入れ子になった型より,又は(入れ子になった

型である場合には)それを囲む入れ子になった型よりも,広いアクセス可能性をもつ。 

注記 この根拠は次のとおりである。C++を含む言語は,アクセスのこの“拡大”を許している。ア

クセスを制限するとセキュリティが向上すると思うのは,間違った考えである。これは,単に

オブジェクトを(暗黙的にメソッド呼出しが発生する。)基底クラスにキャストしても,アクセ

ス可能性は制限されるがメソッドは呼出し可能であることによる。仮想メソッドの上書きを禁

止するためには,宣言されたアクセス可能性に頼るのではなくfinalを使用する。 

CLS規則10 アクセス可能性は,継承されたメソッドを上書きしても変更してはならない。ただし,フ

ァミリ又はアセンブリのアクセス可能性をもつ異なるアセンブリから継承されたメソッドを上書きする場

合は除く。この場合は,ファミリアクセス可能性になる。 

注記  

CLS(使用側) 継承された仮想メソッドへのアクセスを拡大する型を受け入れる必要はない。 

CLS(拡張側) 継承された仮想メソッドへのアクセスを拡大する構文を提供する必要はない。 

CLS(フレームワーク) フレームワークの開示された部分又はフレームワークの利用者によ

る,仮想メソッドへのアクセスを拡大する能力に依存してはならない。 

8.5.3.3 

セキュリティ許可 

メンバへのアクセスは,アセンブリ,型,メソッド,特性又はイベントに添付できるセキュリティ要求

によっても制御される。セキュリティ要求は,型契約(8.6参照)の一部ではなく,継承されない。次の2

種類の要求がある。 

− 継承要求。この要求が型に添付される場合,この型からの継承を望むあらゆる型が指定されたセキュ

リティ許可をもたなければならないことを要求する。この要求が最終(final)でない仮想メソッドに

添付される場合,このメソッドの上書きを望むあらゆる型が指定されたセキュリティ許可をもたなけ

ればならないことを要求する。それ以外のメンバに添付してはならない。 

− 参照要求。この印を付けられた項目への参照を解決しようとする場合,指定されたセキュリティ許可

をもっていなければならない。 

それぞれの種類のただ一つの要求だけを,項目に添付できる。アセンブリに一つのセキュリティ要求を

添付すると,アセンブリの中のすべての型に対して,その型に同じ種類の他の(レベルの)要求が添付さ

れている場合を除き,そのセキュリティ要求が添付される。同様に型にセキュリティ要求を添付すると,

その型のすべてのメンバに対して,そのメンバに同じ種類の他の要求が添付されている場合を除き,その

同じセキュリティ要求が添付される。詳細は,第2章の宣言的セキュリティ及び第4章の

System.Security名前空間の中のクラスを参照。 

8.5.3.4 

入れ子になった型 

30 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

型は,囲む側の型のメンバとなることができる。この場合,それを入れ子になった型という。入れ子に

なった型は,囲む側の型と同じ可視性をもち,囲む側の型の他のメンバと同じアクセス可能性をもつ。こ

のアクセス可能性は,他のどの型が入れ子になった型を参照できるかを決定する。すなわち,あるクラス

が,入れ子になった型のフィールド又は配列要素を定義している,仮引数又は返却値の型が入れ子になっ

た型をとるメソッドをもっているなどの場合,その入れ子になった型は,参照している型に対して可視で

あってしかもアクセス可能になっていなければならない。入れ子になった型は囲む側の型の一部なので,

そのメソッドは,継承されている(親の)型のメンバへのファミリアクセスと同様に,囲む側の型のすべ

てのメンバへのアクセスをもつ(8.9.8参照)。入れ子になった型の名前は,アセンブリではなく囲む側の

型によって有効範囲付けされる(最上位の型だけが,アセンブリによって有効範囲付けされる。)。入れ子

になった型の名前がアセンブリ内で一意になるという要件は存在しない。 

8.6 

契約 

契約には名前が与えられる。契約は,その契約のすべての実装者とすべての利用者との間の識別情報

(8.6.1参照)の集合における共有された想定とする。識別情報は,検査でき強制できる契約の一部とする。 

契約は型ではない。むしろ,型の実装についての要件を指定する。型は,それがどの契約に従っている

か,すなわち,型のすべての実装がどの契約を提供しているかを示す。型の実装は,契約の強制可能な部

分,すなわち,名前の付いた識別情報が実装されたかを検査するために正当性検証できる。契約には次の

種類がある。 

− クラス契約 クラス契約は,クラス定義を用いて指定される。その結果,クラス定義は,クラス契約

及びクラス型の両方を定義する。クラス契約の名前及びクラス型の名前は同じとする。クラス契約は,

クラス型の値の表現を指定する。さらに,クラス契約は,クラス型が提供する他の契約,例えば,ど

のインタフェース,どのメソッド,どの特性及びどのイベントを実装しなければならないかを指定す

る。クラス契約,すなわち,クラス型は,他のクラス型によって提供されることもできる。他のクラ

ス型のクラス契約を提供するクラス型は,そのクラス型から継承されるという。 

− インタフェース契約 インタフェース契約は,インタフェース定義を用いて指定される。そして,イ

ンタフェース定義は,インタフェース契約及びインタフェース型の両方を定義する。インタフェース

契約の名前及びインタフェース型の名前は同じとする。多くの型が,同じインタフェース契約を提供

できる。クラス契約と同様に,インタフェース契約は,そのインタフェースが他のどの契約を提供す

るか,例えば,どのインタフェース,どのメソッド,どの特性及びどのイベントを実装しなければな

らないかを指定する。 

注記 インタフェース型は,値の表現を十分には記述できない。だから,インタフェース型は,ク

ラス契約を提供できず,クラス型又は厳密な型となることはできない。 

− メソッド契約 メソッド契約は,メソッド定義を用いて指定される。メソッド契約は,メソッドの実

装とメソッドの呼出し側との間の契約を指定する名前付き演算とする。メソッド契約は,常に,型契

約(クラス,値型又はインタフェースの契約)の一部であって,特定の名前付き演算を実装する方法

を示す。メソッド契約は,メソッドへの各仮引数が提供しなければならない契約及び返却値がある場

合には返却値が提供しなければならない契約を指定する。 

− 特性契約 特性契約は,特性定義を用いて指定する。名前付き値を扱う演算の拡張可能な集合が存在

する。これは,値を読み,値を変更する標準的な対の操作を含む。特性契約は,特性契約を提供する

型が実装しなければならない演算の部分集合のためのメソッド契約を指定する。一つの型は,多くの

特性契約を提供できるが,与えられた特性契約は,ちょうど一つの型によって提供可能になる。その

background image

31 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

結果,特性定義は,その特性を提供する型の型定義の一部になる。 

− イベント契約 イベント契約は,イベント定義を用いて指定する。名前付きイベントを扱う演算の拡

張可能な集合が存在する。これは,あるイベントに関心があることを登録し,その登録を取り消し,

イベントを発火させるという,三つの標準的なメソッドを含む。イベント契約は,イベント契約を提

供する型が実装しなければならないすべての演算のためのメソッド契約を指定する。一つの型は,多

くのイベント契約を提供できるが,与えられたイベント契約は,ちょうど一つの型によって提供可能

になる。そして,イベント定義は,そのイベントを提供する型の型定義の一部になる。 

8.6.1 

識別情報 

識別情報は,検査可能であって自動的に強制実行可能な契約の一部とする。識別情報は,型及び他の識

別情報に制約を追加することによって形成される。制約は,値又は格納域における演算の使用又は可能な

演算の制限とする。例えば,格納域が異なる値で上書きできるかどうか,値を変更できるかどうかなどは,

制約の例になる。 

すべての格納域は,すべての値と同様に,識別情報をもつ。代入互換性は,制約も含む値の識別情報が

制約も含む格納域の識別情報と互換になることを要求する。4種類の基本的な識別情報,すなわち,型識

別情報(8.6.1.1参照),格納域識別情報(8.6.1.2参照),仮引数識別情報(8.6.1.4参照)及びメソッド識別

情報(8.6.1.5参照)が存在する。5番目の局所識別情報(8.6.1.3参照)は,格納域識別情報の一種とする。 

注記 CLIでの用語“識別情報”は,C#におけるメソッドに対する用語“呼出し情報”に対応するが,

これを,メソッドだけでなく,型,格納域及び仮引数にも拡張したものになっている。これを

明確化するために,新たに“識別情報”を使用する。 

CLS規則11 識別情報に出現するすべての型は,CLS合致でなければならない。インスタンス化された

総称型を構成するすべての型は,CLS合致でなければならない。 

CLS規則12 型及びメンバの可視性及びアクセス可能性は,そのメンバそれ自体が可視であってアクセ

ス可能なときにはいつでも,メンバの識別情報内の型が可視であってアクセス可能でなければならないと

いうようになっていなければならない。例えば,アセンブリの外部で可視である公開メソッドは,そのア

センブリ内でだけ可視な型の実引数をもっていてはならない。あらゆるメンバの識別情報の中で使用され

るインスタンス化された総称型を構成する型の可視性及びアクセス可能性は,そのメンバそれ自体が可視

及びアクセス可能なときはいつでも,可視及びアクセス可能でなければならない。例えば,アセンブリの

外で可視なメンバの識別情報の中に存在するインスタンス化された総称型は,型がそのアセンブリ内部だ

けで可視な総称実引数をもってはならない。 

注記  

CLS(使用側) これらの規則に違反するメンバをもつ型を受け入れる必要はない。 

CLS(拡張側) これらの規則に違反する構文を提供する必要はない。 

CLS(フレームワーク) 移出されている型及びそのメンバで,これらの規則に違反してはな

らない。 

8.6.1.1〜8.6.1.5において,様々な種類の識別情報を示す。これらは,簡単なものから複雑なものへと並

んでいる。すなわち,最も簡単な識別情報は型識別情報であって,格納域識別情報は,型識別情報に省略

可能な幾つかの追加属性を加えたもの,などとなっている。 

8.6.1.1 

型識別情報 

型識別情報は,値及びその使用法に関する契約を定義する。型は,それ自体で,有効な型識別情報にな

background image

32 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

っている。値の型識別情報は,値を調べることによって決定できないし,値のクラス型を知ることによっ

てさえも決定できない。値の型識別情報は,その値がロードされる格納域の格納域識別情報(8.6.1.2参照)

から,又はそれを計算する演算から,導出される。通常,値の型識別情報は,その値がロードされる格納

域の格納域識別情報の型になる。 

注記 この根拠は次のとおりである。“定数”のようなある制約は値の制約であって格納域の制約では

ないから,型識別情報と格納域識別情報との違いが設けられている。この規格の将来の版又は

規格外の拡張で,型制約を導入可能だが,この場合には,この違いが意味をもつ。 

8.6.1.2 

格納域識別情報 

すべての格納域は型をもっている。これは,すべての格納域は格納域識別情報をもつことを意味する。

格納域識別情報は,格納域,その使用法及びその格納域に格納された値の使用法についての制約を定義す

る。有効な型識別情報は,有効な格納域識別情報になる。したがって,格納域識別情報は,型を含み,追

加的に定数制約を含むことができる。格納域識別情報は,格納域の使用に更なる制限を与える格納域制約

を含むことができる。格納域制約は,次による。 

− 初期化値不変制約は,格納域が一度初期化されたらその内容は決して変化しないことを約束(すなわ

ち,要求)する。すなわち,内容はあらゆるアクセスの前に初期化され,初期化の後ではいかなる値

もその格納域には格納できない。内容は,常に初期化値(8.2.3参照)に同一とする。この制約は,論

理的にはあらゆる格納域に適用可能だが,複合型の(静的又はインスタンス)フィールドだけに課さ

れなければならない。 

− リテラル制約は,格納域の値が実際には組込み型の固定された値になっていることを取り決める。そ

の値は,制約の一部として指定される。コンパイラには,その格納域へのすべての参照をその値に置

き換えることが要求され,その結果,VESは,その格納域のために空き領域を割り当てる必要はない。

この制約は,論理的にはあらゆる格納域に適用可能だが,複合型の静的フィールドだけに課されなけ

ればならない。そのように印付けられたフィールドは,CILから参照されてはならない(すなわち,

そのフィールドは,コンパイル時にその定数値にインライン展開されなければならない。)が,自己反

映及びメタデータを直接に扱うツールを用いて利用されてもよい。 

CLS規則13 リテラルであって静的な値は,フィールド初期化メタデータ(第2章参照)を用いて指定

される。CLS合致のリテラルは,そのリテラルと厳密に同じ型(又はそのリテラルがenumである場合は

基礎となる型)のフィールド初期化メタデータで指定される値をもたなければならない。 

注記  

CLS(使用側) 静的なリテラルフィールドのためのフィールド初期化メタデータを読み,参

照されたときには指定された値をインライン展開できなければならない。使用側は,フィール

ド初期化メタデータの型がリテラルフィールドの型と厳密に同じと想定できる。すなわち,使

用側のツールは,値の変換を実装する必要はない。 

CLS(拡張側) フィールド初期化メタデータの型がそのフィールドの型と厳密に一致しない

場合の静的なリテラルフィールドのフィールド初期化メタデータを生成することは避けなけれ

ばならない。 

CLS(フレームワーク) 値の変換を要求するリテラルの値を指定する構文の使用は避けるこ

とが望ましい。コンパイラは,フィールド初期化メタデータに固執せずに,CLS合致のフレー

ムワークを生じるようにそれ自体で変換を実行できることに注意する。ただし,フレームワー

background image

33 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

クは,そのような暗黙的な変換に依存しないことが望ましい。 

注記 格納域に格納された値がアクセスの間にキャッシュされないことを要求するために,格納域に

揮発性制約を与えるのは,もっともらしく思えるかもしれない。それをする代わりに,CILは,

値がキャッシュされないし,既存のキャッシュを用いて計算もされないことを指定するために,

ある命令にvolatile. 接頭辞を含めている。このような制約は,カスタム属性(9.7参照)を用い

て符号化してもよいが,この規格は,そのような属性を規定しない。 

8.6.1.3 

局所識別情報 

局所識別情報は,メソッドの実行中に割り付けられた局所変数に関する契約を指定する。局所識別情報

は,格納域識別情報を完全に含み,それに加えて,次の一つの追加の制約を指定できる。 

byref制約は,対応する格納域の内容が管理下ポインタであることを示す。管理下ポインタは,局所変数,

仮引数,複合型のフィールド又は配列の要素を指せる。しかし,呼出しが遠隔境界(12.5参照)にまたが

っている場合,規格適合処理系は,管理下ポインタの代わりにコピー取込み及びコピー取出しの機構(ポ

インタの先の値を実際にコピーして受け渡す機構)をも使用できる。したがって,プログラムは,真のポ

インタの別名的な振る舞い,その名前から類推される振る舞い,に依存してはならない。 

さらに,一つの特殊な局所識別情報が存在する。型付けされた参照の局所変数識別情報は,その局所変

数が,格納域への管理下ポインタ及びその格納域に格納されてもよい型の実行時表現を含むことを示す。

型付けされた参照識別情報は,byref制約と類似しているが,byrefが型をbyref制約の一部として(すなわ

ち,静的に型記述の一部として)指定するのに対し,型付けされた参照は,動的に型情報を提供する。型

付けされた参照は,それ自体で完全な識別情報であって,他の制約と結合することはできない。特に,そ

れは,型が型付けされた参照になっているbyrefを指定できない。 

型付けされた参照識別情報は,実際には,整数型及び浮動小数点数型と同様に,組込みの値型として表

現される。その型は,基本クラスライブラリ(第4章参照)では,System.TypedReferenceとして知

られ,第2章のアセンブリ言語では,キーワードtypedrefによって示される。この型は,仮引数及び局所

変数についてだけ使用しなければならない。ボックス化したり,フィールド,配列の要素又は返却値の型

として用いてはならない。 

CLS規則14 型付けされた参照は,CLS合致ではない。 

注記  

CLS(使用側) この型を受諾する必要はない。 

CLS(拡張側) この型を定義する構文を提供したり,この型を使用するインタフェース又は

クラスを拡張したりする必要はない。 

CLS(フレームワーク) この型は,移出しているメンバの中に出現してはならない。 

8.6.1.4 

仮引数識別情報 

仮引数識別情報は,個々の値がメソッド呼出しの一部としてどのように渡されるかの制約を定義する。

仮引数識別情報は,メソッド定義によって宣言される。有効な局所識別情報は,有効な仮引数識別情報と

する。 

8.6.1.5 

メソッド識別情報 

メソッド識別情報は,次からなる。 

− 呼出し規約。 

background image

34 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

− メソッドが総称的な場合,総称仮引数の個数。 

− メソッドの各仮引数に対して一つずつの,0個以上の仮引数識別情報の並び。 

− 返却値が生成される場合には,返却値のための型識別情報。 

メソッド識別情報は,メソッド定義によって宣言される。次のただ一つの制約だけが,仮引数識別情報

の制約に加えてメソッド識別情報に追加できる。 

− vararg制約を,対応する位置より後にあるすべての実引数が省略可能であることを示すために,含め

ることができる。これが出現する場合,呼出し規約は,可変長の実引数並びを提供するものでなけれ

ばならない。 

メソッド識別情報は,二つの異なる方法で,すなわち,メソッド定義の一部として,及び関数ポインタ

を通じて呼び出される場合の呼出し側の記述として,使用する。後者の場合,メソッド識別情報は次を示

す。 

− 呼出し規約。これは,プラットフォーム固有の呼出し規約を含むことができる。 

− 渡されるすべての実引数値の型。 

− 必要な場合,固定数の仮引数並びの終了,及び可変数の仮引数並びの開始の格納域を示すvararg標示

子。 

vararg制約は,それがメソッド定義の一部として使用される場合,呼出し規約の選択によって表現され

る。 

CLS規則15 vararg制約はCLSの一部ではなく,CLSが提供する呼出し規約だけを標準の管理下呼出

し規約とする。 

注記  

CLS(使用側) 可変数の実引数並び又は管理外呼出し規約をもつメソッドを受け入れる必要

はない。 

CLS(拡張側) vararg(をもつ)メソッド又は管理外呼出し規約を宣言する構文を提供する

必要はない。 

CLS(フレームワーク) vararg(をもつ)メソッドも,管理外呼出し規約をもつメソッドも,

明示的に移出してはならない。 

8.7 

代入互換性 

代入互換性は,(型識別情報によって静的に示される)値Vを(格納域識別情報によって示される)格

納域Lに格納する能力を表し,L := Vと簡略表記する。Vについての型識別情報は静的に記述されるから,

実際には,Vは,その識別情報が記述する型の値ではないかもしれず,むしろ,その型と互換なものかも

しれない。格納域又は値は,型System.Voidをもっていてはならない。 

代入互換性の正式な規定は,第3章に示す。そこでは,型互換性の正当性検証として参照されている。

本質的には,値Vは,それが次の条件の一つを満たす場合に,格納域Lと代入互換とする。 

− Vの型識別情報によって参照される厳密な静的な型が,その格納域識別情報の厳密な型と一致する。 

− Vが総称型識別情報G<U1,...,Un>によって記述され,Lが総称型識別情報H<T1,…,Tn>によって記述さ

れる場合,G=Hであって,かつ,Gの各総称仮引数 Ui の共変反変の注記をvar̲iとしたときに,次

のことがいえる場合及びその場合に限り,VはLと代入互換とする。 

− var̲i = none,すなわち,Tiが値型のとき又はTiが総称仮引数のとき,Uiは,Tiと同じ厳密な型で

ある。 

35 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

− var̲i = + のとき,Ti := Uiである(すなわち,共変のとき,Uiのインスタンスは,型Tiの格納域に

格納できる。)。 

− var̲i = - のとき,Ui := Tiである(すなわち,反変のとき,Tiのインスタンスは,型Uiの格納域に

格納できる。)。 

− Vが型識別情報U[]によって記述され,Lが格納域識別情報T[]によって記述されるとした場合,T及

びUが参照型又はインタフェースのいずれかであり,T := Uであって,その配列型が両方ともベクト

ル(添字が0から始まり次元数が1)か又は両方ともベクトルでなく同じ階数をもつ場合及びその場

合に限り,VはLと代入互換とする。 

注記 これは,配列型が共変であることを意味する。 

− 型識別情報U[]によって記述されるVは,System.Collections.Generic.IList<U>と代入互換

であって,BがUによって提供される型の集合である場合には, 

System.Collections.Generic.IList<B>とも代入互換とする。 

− Vの型識別情報が,列挙型であって,Lの型識別情報が,その列挙型の基礎となる型とする。 

− Vの型識別情報が,符号付き整数へのbyref(8.6.1.3参照)であって,Lの格納域識別情報が,同じ大

きさの符号なし整数へのbyrefである場合,又はその逆の場合。例えば,int32& := uint32&。 

− Vの型識別情報がint32であって,Lの格納域識別情報がboolである場合。 

注記 CLIスタックは,たとえ,shortの整数がプッシュされても,int32だけを追跡する。第3

章を参照する。 

− Vの厳密な型が提供する型の一つが,Lの型と代入互換である場合。これによって,例えば,基底ク

ラスから継承された(すなわち,基底クラスの型制約を提供する)クラスのインスタンスを,型が基

底クラスの型である格納域に格納できる。 

注記 格納域制約は,ちょうど,型制約及び二つの追加的な可能な制約(リテラル及び定数)にな

っていることを思い出してほしい。つまり,格納域制約は自然な方法で型制約に変換できる。 

この規則の集合のもとで,代入互換性の推移性は維持される。つまり,L:=Vであり,M:=Lであれば,

M:=Vとする。 

− 符合付き及び符号なしの整数の基礎的な型は,互いに代入できる。例えば,int8 := uint8は正当

とする。このためには,boolはuint8と代入互換でなければならず,その逆もそうであるとする。

つまり,bool := uint8及びその逆の代入は正当になる。これは,同じ大きさの符号付き及び符号

なしの整数の基礎的な型の配列に対しても正しい。例えば,int32[] := uint32[]は正当とする。 

8.8 

型安全及び正当性検証 

型は契約を指定するから,与えられた実装がこれらの契約に従っているかどうかを知ることが重要にな

る。契約の強制可能部分(名前を付けられた識別情報)に従う実装は,型安全という。契約の重要な部分

は,名前をメモリの中の実装及び格納域へ対応付けることだけでなく,名前をもつ項目の可視性及びアク

セス可能性に関する制限を扱う。 

型安全な実装は,格納域の格納域識別情報と代入互換(8.7参照)である格納域の型識別情報が示す値だ

けを格納する(8.6.1参照)。型安全な実装は,決して,値の厳密な型が定義しない値に演算を適用しない。

型安全な実装は,その実装に対して可視であってアクセス可能でもある格納域だけにアクセスする。型安

全な実装では,値の厳密な型は変化しない。 

正当性検証は,実装を調べ,それが型安全であると表明する機械的な処理とする。正当性検証は,その

処理が,実装が型安全であることを証明する場合,成功したという。正当性検証は,その処理が,実装の

36 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

型安全性を証明しない場合,失敗したという。正当性検証は,必然的に保守的になる。型安全な実装に対

して失敗を報告できる。しかし,型安全でない実装に対して成功を報告してはならない。例えば,ほとん

どの正当性検証処理は,ポインタに基づく算術計算(ポインタ自体の算術計算)を行う実装を,たとえ,

その実装が実際には型安全であっても,正当性検証失敗として報告する。 

正当性検証の基礎とすることが可能な多くの異なる処理がある。最も簡単な処理は,すべての実装は型

安全でないとするものである。これは(論理的には)正しいし効率的だが,明らかに実用的には役に立た

ない。処理は,より多くの資源(時間及びメモリ)を費やすことによって,より多くの型安全な実装を正

しく識別できる。しかし,有限時間で誤りなく,すべての実装を型安全かそうでないか正しく識別する機

械的な処理は,存在不可能なことが証明されている。したがって,特定の正当性検証処理の選択は,決定

のために利用可能な資源と,異なるプログラム構成要素の型安全を検出することの重要性とに基づいた,

技術的な問題になる。 

8.9 

型定義側 

型定義側は,既存の型から新しい型を構成する。暗黙的な型(例えば,組込み型,配列,関数ポインタ

を含むポインタなど)は,使用されるときに定義される。識別情報での暗黙的な型の記述は,それ自体で,

その型の完全な定義になる。暗黙的な型は,VESが,メンバ,インタフェースなどの標準的な集合をもつ

インスタンスを作り出すことを可能にする。暗黙的な型は,利用者が提供する名前を必要としない。 

その他のすべての型は,明示的な型の定義を用いて明示的に定義されなければならない。明示的な型定

義側は,次による。 

− インタフェース定義 インタフェース型を定義するために使用する。 

− クラス定義 次のいずれかでありうるクラス型を定義するために使用する。 

− (委譲を含む)オブジェクト型 

− 値型及びそれの関連するボックス化型 

注記 クラス定義は常にクラス型を定義するが,すべてのクラス型がクラス定義を要求するわけでは

ない。暗黙的に定義される配列型及びポインタ型も,クラス型である(8.2.3参照)。 

同様に,クラス定義が定義するすべての型が,オブジェクト型になるわけではない。配列型,

明示的に定義されたオブジェクト型及びボックス化型は,オブジェクト型である。ポインタ型,

関数ポインタ型及び値型は,オブジェクト型ではない(8.2.3参照)。 

クラス定義,インタフェース定義及び値型定義は,総称型定義として知られる機能であって,(型の)仮

引数をもつことができる。すなわち,クラス型,インタフェース型又は値型の定義は,総称仮引数を含む

ことができる。使用されるときには,総称クラス型,総称インタフェース型又は総称値型に特定のインス

タンス化が行われる。このとき,総称仮引数は,特定の総称実引数に束縛される。総称仮引数に制約を与

えることができる。その結果,これら制約に一致する総称実引数だけが,インスタンス化で使用できる。 

8.9.1 

配列型 

配列型は,配列の要素型,配列の次元数,並びに配列の各次元の上限及び下限(限界)を指定すること

によって定義しなければならない。その結果,配列型のこれとは異なる定義は必要ない。(配列への添字子

と同様に)限界は,符号付き整数でなければならない。各次元の実際の限界は実行時にだけ分かるが,識

別情報が,[例えば,限界なし,下限(値),上限及び下限の両方(の値)といった]コンパイル時に分か

る情報を指定できる。 

配列要素は,列を主とする(優先する)順番で,配列オブジェクト内に配置されなければならない。す

なわち,最右配列次元と関連付けられた要素が,最小の添字から最大の添字へと連続的に配置されなけれ

background image

37 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

ばならない。各配列要素に割り付けられる実際の格納域は,プラットフォーム固有の詰物を含んでもよい。

この格納域のバイト単位での大きさが,sizeof命令によって,それがその配列要素の型に適用されたと

きに,返される。 

配列型の値は,オブジェクトとする。そこで,配列型は,オブジェクト型の一種になる(8.2.3参照)。

配列オブジェクトは,CTSによって,配列の要素型の値を格納した格納域の繰返しと定義される。繰り返

される値の個数は,配列の次元数及び限界によって決定される。 

格納域識別情報ではなく型識別情報だけが,配列の要素型として許される。 

厳密な配列型は,それが要求されたときに,VESによって自動的に生成される。そして,配列型の演算

は,CTSによって定義される。これらは,一般的には,大きさ及び下限の情報に基づいて配列を割り付け

ること,値の読み書きのために配列に添字指定すること,配列の要素のアドレス(管理下ポインタ)を計

算すること,並びに配列に格納された値の次元数,限界及び総数を問い合わせることである。 

さらに,要素型Tをもつ生成されたベクトルは,インタフェース 

System.Collections.Generic.IList<U>(8.7参照)を実装する。ただし,U := Tとする。 

CLS規則16 配列は,CLS合致の型をもつ要素をもち,配列のすべての次元は,0の下限をもたなけれ

ばならない。項目が配列であるという事実及び配列の要素型だけが,多重定義を区別する目的で必要とな

る。多重定義が二つ以上の配列型に基づいている場合,要素型は名前付きの型でなければならない。 

注記 いわゆる“非く(矩)形配列”は,CLS合致とする。しかし,複数の配列型を多重定義する場

合,それらは,型Sytem.Arrayの1次元で添字が0から始まる配列とする。 

CLS(使用側) System.Arrayのインスタンスを扱う場合であっても,非CLSの型の配列

を扱える必要はない。多重定義の解決には,配列型の完全な複雑さを意識する必要はない。プ

ログラマは,配列型の全範囲についての言語構文が存在しない場合には,System.Arrayのイ

ンスタンス上のGetメソッド,Setメソッド及びAddressメソッドへのアクセスをもつこと

が望ましい。 

CLS(拡張側) 配列の非CLSの型を定義するための構文,又は非CLSの配列型を使うイン

タフェース若しくはクラスを拡張するための構文を提供する必要はない。型System.Array

へのアクセスを提供しなければならないが,すべてのインスタンスがCLS合致の型をもつと想

定してよい。配列の仮引数をもつ継承されたメソッドを上書きするためには完全な識別情報を

使用しなければならないが,配列型の完全な複雑さをプログラマに見せる必要はない。プログ

ラマは,配列型の全範囲についての言語構文が存在しない場合には,System.Arrayのインス

タンス上のGetメソッド,Setメソッド及びAddressメソッドへのアクセスをもつことが望

ましい。 

CLS(フレームワーク) 非CLSの配列型が,移出されているメンバの中に現れてはならな

い。可能な場合には,1次で,添字が0から始まる単純な名前付きの型の配列だけを使用しな

ければならない。これは,これらの配列が広範囲のプログラム言語で提供されていることによ

る。配列型の多重定義は,避けることが望ましく,使用する場合には,ここで示した制限に従

わなければならない。プログラマは,配列型の全範囲についての言語構文が存在しない場合に

は,System.Arrayのインスタンス上のGetメソッド,Setメソッド及びAddressメソッド

へのアクセスをもつことが望ましい。 

配列型は,すべての配列型が型System.Arrayから継承されているという階層をなす。これは,その

background image

38 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

要素の型,次元数,又は上限及び下限にかかわらず,すべての配列を表現する抽象クラス(8.9.6.2参照)

といえる。VESは,それぞれの区別可能な配列型に対して一つの配列型を生成する。一般に,配列型は,

その要素の型及び次元数によってだけ区別できる。しかし,VESは,1次元で,添字が0から始まる配列

(ベクトルとしても知られているもの)を特殊なものとして取り扱う。ベクトルもその要素の型によって

区別されるが,ベクトルは,0でない下限をもつ同じ要素型の1次元配列とは区別される。0次元の配列は

提供されない。 

第2章で示されるとおりのCIL構文を用いて,表2に例を示す。 

表2−配列の例 

型の静的な規定 

構成される実際の型 

CLSで許されるかどうか 

int32[] 

int32のベクトル 

許される 

int32[0..5] 

int32のベクトル 

許される 

int32[1..5] 

int32の次元数1の配列 

許されない 

int32[,] 

int32の次元数2の配列 

許される 

int32[0..3, 0..5] 

int32の次元数2の配列 

許される 

int32[0.., 0..] 

int32の次元数2の配列 

許される 

int32[1.., 0..] 

int32の次元数2の配列 

許されない 

8.9.2 

管理外ポインタ型 

管理外ポインタ型(単に“ポインタ型”としても知られる。)は,そのポインタが参照する格納域のため

の格納域識別情報を指定することによって定義される。ポインタ型のあらゆる識別情報は,この格納域識

別情報を含む。だから,ポインタ型の個別の定義は必要ない。 

ポインタ型は参照型だが,ポインタ型の値はオブジェクトではない(8.2.3参照)。だから,ポインタ型

の値を与えて,その厳密な型を決定することはできない。CTSは,ポインタ型に関して二つの型安全な演

算を提供する。一つは,ポインタが参照する格納域から値をロードする演算であって,もう一つは,その

格納域に代入互換な値を格納する演算とする。CTSは,ポインタ型に関して三つの演算,バイトに基づく

アドレスの算術計算を行う三つの演算も提供する。すなわち,ポインタに整数を加算すること,ポインタ

から整数を減算すること及び一つのポインタからもう一つのポインタを減算することである。最初の二つ

の演算の結果は,元のポインタと同じ型識別情報へのポインタとなる(第3章参照)。 

CLS規則17 管理外ポインタ型は,CLS合致ではない。 

注記  

CLS(使用側) 管理外ポインタ型を使えるようにする必要はない。 

CLS(拡張側) 管理外ポインタ型を定義したりアクセスしたりする構文を提供する必要はな

い。 

CLS(フレームワーク) 管理外ポインタ型を外部に移出してはならない。 

8.9.3 

委譲 

委譲は,オブジェクト指向において,関数ポインタに相当するものである。関数ポインタとは違い,委

譲は,オブジェクト指向であって,型安全で,安全(secure)である。委譲は,基底型System.Delegate

から派生するクラスを定義することによって生成される(第4章参照)。それぞれの委譲型は,適切な仮

引数をもつInvokeという名前のメソッドを提供しなければならず,委譲の各インスタンスは,そのInvoke

background image

39 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

メソッドへの呼出しを特定のオブジェクト上の一つ以上の互換な静的メソッド又はインスタンスメソッド

に転送する。委譲インスタンスが委譲するオブジェクト及びメソッドは,委譲インスタンスが生成された

ときに選ばれる。 

インスタンス構築子及びInvokeメソッドに加えて,委譲は,任意選択で,二つの付加的なメソッド

BeginInvoke及びEndInvokeをもつことができる。これらは,非同期呼出しのために使用する。 

大部分の場合,委譲は,単にある種の利用者定義クラスとして出現するが,しっかりと制御されている。

メソッドの実装は,利用者コードではなくVESによって提供される。委譲型で定義できる追加的なメンバ

は,静的メソッド又はインスタンスメソッドだけとする。 

8.9.4 

インタフェース型定義 

インタフェース定義は,インタフェース型を定義する。インタフェース型は,同じ名前のインタフェー

ス契約をもつオブジェクト型によって実装されなければならないメソッド,格納域及び他の契約の名前付

きグループとする。インタフェース型は,常に,値の不完全な記述であって,クラス型又は厳密な型を定

義できないし,オブジェクト型にもなれない。 

0個以上のオブジェクト型が一つのインタフェース型をもつことができ,オブジェクト型だけがインタ

フェース型をもつことができる。インタフェース型は,それをもつオブジェクト型が他の(指定された)

インタフェース型ももたなければならないと要求できる。名前付きインタフェース契約をもつオブジェク

ト型は,そのインタフェース型によって指定された(しかし実装はされていない)メソッド,格納域及び

他の契約の完全な実装を与えなければならない。その結果,オブジェクト型の値は,そのオブジェクト型

がもつすべてのインタフェース型の値にもなっている。インタフェース契約の提供は,宣言されるが推論

はされない。すなわち,インタフェース型が要求するメソッド,格納域及び他の契約の実装の存在は,イ

ンタフェース契約の提供を意味しない。 

CLS規則18 CLS合致のインタフェースは,それを実装するためにCLS合致でないメソッドの定義を

要求してはならない。 

注記  

CLS(使用側) そのようなインタフェースを扱う必要はない。 

CLS(拡張側) そのようなインタフェースを扱うための機構を提供する必要はない。 

CLS(フレームワーク) 外部使用のために定義されたインタフェース上のCLS合致でない

メソッドを開示してはならない。 

インタフェース型は,インタフェース型の値の表現について何も示していないから,必ず,不完全にな

っている。この理由によって,インタフェース型は,静的フィールドを宣言できるが,そのインタフェー

ス型の値のためのフィールド定義(すなわち,インスタンスフィールド)を提供してはならない(8.4.3参

照)。 

同様に,インタフェース型定義は,その型の値に関するメソッドのための実装を提供してはならない。

しかし,インタフェース型定義は,提供している型によって実装されなければならないメソッド契約(メ

ソッド名及びメソッド識別情報)を定義できるし,通常は定義する。静的メソッド(8.4.3参照)はインタ

フェース型の値にではなくてその型それ自体と関連しているから,インタフェース型定義は,静的メソッ

ドを定義し実装できる。 

インタフェースは,静的メソッド又は仮想メソッドをもつことができるが,インスタンスメソッドをも

ってはならない。 

background image

40 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

CLS規則19 CLS合致のインタフェースは,静的メソッドを定義してはならないし,フィールドを定

義してもならない。 

注記 CLS合致インタフェースは,特性,イベント及び仮想メソッドを定義できる。 

CLS(使用側) これらの規則に違反するインタフェースを受け入れる必要はない。 

CLS(拡張側) これらの規則に違反するインタフェースを編集する構文を提供する必要は 

ない。 

CLS(フレームワーク) これらの規則に違反するインタフェースを外部に開示してはならな

い。静的メソッド,インスタンスメソッド又はフィールドが要求される場合,それらを提供す

る別々のクラスを定義できる。 

インタフェース型は,そのインタフェースを提供するオブジェクト型によって実装されなければならな

いイベント契約及び特性契約も定義できる。イベント契約及び特性契約はメソッド契約の集合に還元され

る(8.6参照)から,メソッド定義のための規則が適用される。更なる情報については,8.11.3及び8.11.4

を参照。 

インタフェース型定義は,そのインタフェース型の実装が提供することを要求される他のインタフェー

ス契約を指定できる。固有の問題については,8.9.11を参照。 

インタフェース型は,8.5.3で示したとおり,そのインタフェース型が参照可能な場所を制御する可視性

属性を与えられている。インタフェース型定義は,そのインタフェース型を提供するオブジェクト型定義

とは分離されている。その結果,インタフェース型及びそれを実装するオブジェクト型に対して異なる可

視性をもつことが可能になっており,それが望ましいことが多い。しかし,アクセス可能性属性はインタ

フェースそれ自体よりも実装の型に関係しているから,インタフェースのすべてのメンバは,公開のアク

セス可能性をもたなければならず,セキュリティ許可をそのメンバ又はインタフェースそれ自体に添付す

ることはできない。 

8.9.5 

クラス型定義 

インタフェース以外のすべての型であって,CTSが自動的に定義を供給する型は,クラス定義によって

定義される。クラス型は,そのクラス型の値の表現及びそのクラス型が提供する契約(クラス,インタフ

ェース,メソッド,特性及びイベント)の完全な規定とする。その結果,クラス型は厳密な型になる。ク

ラス定義における,そのクラスが抽象クラス型であると指定している場合を除いて,そのクラス型を定義

するだけでなく,そのクラス型が提供する契約すべてのための実装も提供する。 

クラス定義及びそのクラス型の実装は,常に,あるアセンブリの中に存在する。アセンブリは,ロード

可能なコードモジュールと,一緒に機能単位を実装する他の資源とから構成された集合とする。 

注記 クラス定義は常にクラス型を定義するが,すべてのクラス型がクラス定義を要求するわけでは

ない。配列型及びポインタ型は,暗黙的に定義されるが,それらもクラス型になる(8.2.3参照)。 

明示的クラス定義は,次を定義するために使用する。 

− オブジェクト型(8.2.3参照)。 

− 値型及びその関連ボックス化型(8.2.4参照)。 

明示的クラス定義は,次を行う。 

− クラス型に名前を付ける。 

− 暗黙的にそのクラス型名に一つの有効範囲,すなわち,そのクラス定義を含むアセンブリを割り当て

る(8.5.2参照)。 

41 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

− 同じ名前のクラス契約を定義する(8.6参照)。 

− フィールド,メソッド,特性及びイベントのためのメンバ定義を用いて,そのクラス型のすべての値

の表現及び妥当な演算を定義する(8.11参照)。 

− クラス型の静的メンバを定義する(8.11参照)。 

− そのクラスが提供する他のインタフェース契約及びクラス契約を指定する。 

− そのクラス型が提供するメンバ契約及びインタフェース契約のための実装を供給する。 

− 型の可視性を明示的に公開又はアセンブリのいずれかと宣言する(8.5.3参照)。 

− 任意選択で,型を初期化するために呼び出される(.cctorと呼ばれる)メソッドを指定できる。 

このような型初期化の実行がいつ引き起こされるのか及び何が引き起こすかの意味は,次による。 

1) 型は,型初期化子メソッドをもつことができるし,もたなくてもよい。 

2) 型は,その型初期化子メソッドのために緩和された意味をもつと指定できる(次では,便宜のため

に,この緩和された意味をBeforeFieldInitと呼ぶ。)。 

3) BeforeFieldInitと印付けされている場合,型の初期化子メソッドは,その型のために定義された静的

フィールドへの最初のアクセスの時点又はその前のある時点で実行される。 

4) BeforeFieldInitと印付けされていない場合,型の初期化子メソッドは,次の時点で実行される(すな

わち,次の時点までに引き起こされる。)。 

− その型の静的フィールドへの最初のアクセス。 

− その型の静的メソッドの最初の呼出し。 

− その型のあらゆる構築子の最初の呼出し。 

5) 型の初期化子メソッドの実行は,その基底型が定義する初期化子メソッドの自動的な実行を引き起

こさないし,その型が実装するインタフェースの自動的な実行をも引き起こさない。 

参照型については,構築子が,nullでないインスタンスを生成するために呼び出されなければならない。

そこで,参照型では,nullでないインスタンス上でインスタンスフィールドがアクセスでき,メソッドが

呼び出せる前に,.cctorが,呼び出される。値型については,構築子なしに“すべて0”のインスタンスが

生成できる(ただし,この値だけが構築子なしで生成できる。)。そこで,値型では,“すべて0”ではない

値型のインスタンスに対してだけ,.cctorが呼び出されることを保証する。 

注記1 このことは,“this”実引数がnullである場合,インスタンスメソッドが呼び出される前

に.cctorが呼び出されないかもしれないという点で,この規格の第1版から,参照クラスであ

る場合の意味を少し変更する。クラス構築子を回避するという付加的な性能向上が,この変

更を裏付ける。 

注記2 BeforeFieldInitの振る舞いは,興味深い副作用を伴わない初期化コードのために意図されてい 

る。この場合,(実行の)厳密なタイミングは問題ではない。BeforeFieldInitの意味のもとで

は,型初期化子は,その型の静的フィールドへの最初のアクセス時又はその前に実行されて

よい。実行の時点は,CLIの裁量による。 

(プログラム)言語がより厳密な振る舞いを提供することを望む場合,例えば,型の初期

化が自動的に基底クラスの初期化子の実行を,最上位から最下部へという順番で,引き起こ

すなどを望む場合,言語は,次のいずれかによってそれを行うことができる。 

− それぞれのクラスの基底クラス及び/又はそのクラスが実装するインタフェースの隠ぺい

された静的フィールドにアクセスする,隠ぺいされた静的フィールド及びコードを,その

クラスの構築子の中に定義すること。 

42 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

−System.Runtime.CompilerServices.Runtime-Helpers.RunClassConstructor

に対して明示的な呼出しを行うこと(第4章参照)。 

8.9.6 

オブジェクト型定義 

すべてのオブジェクトは,オブジェクト型のインスタンスとする。オブジェクトのオブジェクト型は,

オブジェクトが生成されたときに設定され,不変とする。オブジェクト型は,インスタンスの物理的構造

及びその上で許される演算を記述する。同じオブジェクト型のすべてのインスタンスは,同じ構造及び同

じ使用可能な演算をもつ。オブジェクト型は,配列型を除いて,クラス型定義によって明示的に宣言され

る。配列型は,本来的にVESによって提供される。 

8.9.6.1 

有効範囲及び可視性 

オブジェクト型定義は,クラス型定義なので,オブジェクト型の名前の有効範囲を暗黙的にそのオブジ

ェクト型定義を含むアセンブリと指定する(8.5.2参照)。同様に,オブジェクト型定義は,オブジェクト

型の可視性の属性(公開又はアセンブリのいずれか)も明示的に示さなければならない(8.5.3参照)。 

8.9.6.2 

具象性 

オブジェクト型は,オブジェクト型定義によってabstractと印付けできる。abstractと印付けられていな

い(抽象ではない)オブジェクト型は,定義によって具象的(concrete)となる。オブジェクト型だけが抽

象と宣言できる。抽象オブジェクト型だけが,型又はVESが実装を提供しないメソッド契約を定義するこ

とを許される。このようなメソッド契約を抽象メソッドという(8.11参照)。抽象クラスのすべてのメソッ

ドが抽象である必要はない。 

型が抽象メソッドをもつかどうかに関係なく,抽象オブジェクト型のインスタンスを生成しようとする

ことはエラーとする。抽象オブジェクト型から派生するオブジェクト型は,それが,基底オブジェクト型

の中のすべての抽象メソッドのための実装を提供し,それ自体はabstractと印付けられていない場合,

具象とできる。インスタンスは,このような具象派生クラスから構成できる。格納域は抽象型をもつこと

ができ,その抽象型から派生した具象型のインスタンスをその格納域に格納できる。 

8.9.6.3 

型メンバ 

オブジェクト型定義は,その型のメンバすべてのためのメンバ定義を含む。簡単にいうと,型のメンバ

は,値が格納されるフィールド,呼び出してよいメソッド,利用可能な特性及び発生可能なイベントを含

む。型の各メンバは,8.4で示したとおりの属性をもってよい。 

− オブジェクト型のフィールドは,そのオブジェクト型を構成する構成要素の断片を指定することによ

って,オブジェクト型の値の表現を指定する(8.4.1参照)。静的フィールドは,オブジェクト型それ

自体と関連するフィールドを指定する(8.4.3参照)。オブジェクト型のフィールドは,名前が付けら

れており,格納域識別情報を通じて型付けされている。型のメンバの名前は,その型を有効範囲とし

て与えられる(8.5.2参照)。フィールドは,フィールド定義を用いて宣言される(8.11.2参照)。 

− オブジェクト型のメソッドは,その型の値における演算を指定する(8.4.2参照)。静的メソッドは,

型それ自体についての演算を指定する(8.4.3参照)。メソッドは,名前が付けられており,メソッド

識別情報をもつ。メソッドの名前は,その型を有効範囲として与えられる(8.5.2参照)。メソッドは,

メソッド定義を用いて宣言される(8.11.1参照)。 

− オブジェクト型の特性は,値を読むメソッド及び書くメソッドを通じてアクセス可能な名前の付いた

値を指定する。特性の名前は,メソッドをグループ化したものである。メソッドそれ自体も,メソッ

ド識別情報を通じて名前付けされ型付けされている。特性の名前は,その型を有効範囲として与えら

れる(8.5.2参照)。特性は,特性定義を用いて宣言される(8.11.3参照)。 

background image

43 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

− オブジェクト型のイベントは,アクセス操作子を通じて登録者の関心があることを登録及び/又は登

録解除してよい名前付きの状態遷移を指定する。状態が変化するとき,登録者は状態遷移を通知され

る。イベントの名前は,アクセス操作子メソッドをグループ化したものである。メソッドそれ自体も,

メソッド識別情報を通じて名前付けされ型付けされている。イベントの名前は,その型を有効範囲と

して与えられる(8.5.2参照)。イベントは,イベント定義を用いて宣言される(8.11.4参照)。 

8.9.6.4 

インタフェース契約の提供 

オブジェクト型定義は,0個以上のインタフェース契約を提供すると宣言できる。インタフェース契約

についての提供を宣言すると,そのインタフェース契約を完全に実装するオブジェクト型の実装に要件が

課せられる。インタフェース契約を実装することは,常に,メソッドの要求された集合,すなわち,その

インタフェース型が要求するメソッド群を実装することに還元される。 

オブジェクト型が実装する異なる型,すなわち,オブジェクト型及び実装されたインタフェース型は,

それぞれ,名前の付いたメンバの分離した論理グループに分けられる。クラスFooがインタフェースIFoo

を実装し,Ifooがメンバメソッドint a()を宣言し,Fooもメンバメソッドint a()を宣言している

場合,二つのメンバ,IFooインタフェース型の中のメンバ及びFooクラス型の中のメンバが存在する。

Fooの実装は,両方の実装を提供し,潜在的に共有する。 

同様に,クラスが一つのメソッドint a()を定義する二つのインタフェースIFoo 及びIBarを実装す

る場合,そのクラスは,各インタフェースについて一つずつの二つのメソッド実装を提供することになる。

ただし,それらは,実際の実装のコードを共有できる。 

CLS規則20 CLS合致のクラス,値型及びインタフェースは,CLS合致でないメンバの実装を要求し

てはならない。 

注記  

CLS(使用側) この規則に違反するクラス,値型又はインタフェースを受け入れる必要はな

い。 

CLS(拡張側) この規則に違反するクラス,値型又はインタフェースを作成する構文を提供

する必要はない。 

CLS(フレームワーク) この規則に違反するクラス,値型又はインタフェースを外部に開示

してはならない。CLS合致のフレームワークがCLS合致ではないインタフェースを実装するク

ラスを開示している場合,そのフレームワークは,すべてのCLS合致ではないメンバの(具象

的な)実装を提供しなければならない。このことは,CLS拡張側がCLS合致ではないメンバを

実装するための構文を必要としないことを保証する。 

8.9.6.5 

クラス契約の提供 

オブジェクト型定義は,一つの他のクラス契約の提供を宣言できる。他のクラス契約の提供を宣言する

ことは,オブジェクト型の継承と同義とする(8.9.9参照)。 

8.9.6.6 

構築子 

オブジェクト型の新しい値は,構築子を通じて生成される。構築子は,メソッド契約の特殊な形式を通

じて定義されるインスタンスメソッドでなければならない。ここで,この特殊な形式は,メソッド契約を

特定のオブジェクト型のための構築子として定義する。オブジェクト型のための構築子は,オブジェクト

型定義の一部とする。CTS及びVESは,確実に,適正に定義された構築子だけをオブジェクト型の新しい

値を作成するために使用するようにするが,新しく構築されたオブジェクトが完全に正しいかどうかは,

background image

44 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

構築子自体の実装に依存する。 

オブジェクト型は,少なくとも一つの構築子メソッドを定義しなければならないが,そのメソッドは,

公開である必要がない。構築子を呼び出すことによってオブジェクト型の新しい値を生成するには,次の

過程を順番に行う。 

1) 新しい値のための空領域を管理下メモリの中に割り付ける。 

2) 新しい値のVESデータ構造を初期化し,利用者に見えるメモリをゼロクリアする。 

3) オブジェクト型のための指定された構築子を呼び出す。 

構築子の内部で,オブジェクト型は,それが選択するいかなる初期化をも行える(何もしないという選

択もできる)。 

CLS規則21 オブジェクト構築子は,継承されたインスタンスデータへのアクセスが発生する前に,そ

の基底クラスのクラス構築子を呼び出さなければならない。これは,値型には適用されない。値型は,構

築子をもつ必要はない。 

CLS規則22 オブジェクト構築子は,オブジェクトの生成の一部として以外では呼び出されてはならな

いし,一つのオブジェクトは,2回初期化されてはならない。 

注記  

CLS(使用側) オブジェクトが生成されるときに呼び出される構築子を選択するための構文

を提供しなければならない。 

CLS(拡張側) 異なる識別情報をもつ構築子メソッドを定義するための構文を提供しなけれ

ばならない。構築子がこれらの規則に従わない場合は,コンパイルエラーを発生してもよい。 

CLS(フレークワーク) オブジェクト生成は(幾つかの)構築子の一つへの呼出しを含み,

オブジェクトは2回は初期化されないと想定できる。System.Object.MemberwiseClone

(第4章参照)及び(オブジェクトの遠隔実行を含む)直列化解除は,構築子を実行してはな

らない。 

8.9.6.7 

終了化子 

オブジェクト型を生成するクラス定義は,そのクラスのインスタンスがもはや到達可能ではない場合に

呼び出される(終了化子という)インスタンスメソッドを供給できる。クラスSystem.GC(第4章参照)

は,メソッドSuppressFinalize 及びメソッドReRegisterForFinalizeを通じて,終了化子の振る

舞いに制限された制御を提供する。CLI規格合致実装は,終了化子の振る舞いに影響する追加的な機構を

指定し提供できる。 

CLI規格合致実装は,次の場合を除き,同じオブジェクトに対して終了化子を2回自動的に呼び出して

はならない。例外の場合は,次による。 

− (SuppressFinalizeへの呼出しが後続しない)ReRegisterForFinalizeへの呼出しが挟み込

まれた場合。 

− プログラムが,この振る舞いの代替となるものを生成するように明示的に指定された実装固有の機構

を呼び出した場合。 

注記 この根拠は次のとおりである。プログラマは,終了化子を複数回実行することを引き起こす明

示的な動作をさせない限り,与えられたオブジェクトに関して,終了化子は正確に1回実行さ

れることを期待している。 

値型に対して終了化子を定義することは正当とする。しかし,その終了化子は,値型のボックス化され

45 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

たインスタンスに対してだけ実行される。 

注記 プログラマは終了化子が呼び出されることに依存するかもしれないから,CLIは,終了する前

に,SuppressFinalizeへの呼出しによる終了化をまぬがれていたすべてのオブジェクトに

対して,確実に終了化子が呼び出されるようにあらゆる努力を行うことが望ましい。実装は,

この振る舞いを保証できないあらゆる条件を指定することが望ましい。 

注記 終了化子が迅速に呼び出されない場合には資源が枯渇するかもしれないから,CLIは,インス

タンスがアクセス可能でなくなった後すぐに終了化子を確実に呼び出すことが望ましい。終了

化子の呼出しのきっかけをメモリの不足に依存することは受け入れられる方策だが,実装者は,

(きっかけを計る)追加的な測度の使用を考慮したほうがよい。 

8.9.7 

値型定義 

クラス定義が定義するすべての型がオブジェクト型というわけではない(8.2.3参照)。特に,値型はオ

ブジェクト型ではないが,クラス定義を用いて定義される。値型のためのクラス定義は,(ボックス化され

ていない)値型及び関連するボックス化型の両方を定義する(8.2.4参照)。クラス定義のメンバは,それ

ら両方の表現を定義する。 

1) 非静的メソッド(すなわち,インスタンスメソッド又は仮想メソッド)が値型で呼び出される場合,

そのthisポインタは,インスタンスへの管理下参照になる。一方,そのメソッドが関連するボック

ス化型で呼び出される場合,thisポインタは,オブジェクト参照になる。 

値型のインスタンスメソッドは,ボックス化されていない型への管理下ポインタであるthisポイ

ンタを受け取り(その値型が実装するインタフェース上のものも含む),仮想メソッドは,ボックス

化された型のインスタンスを受け取る。 

2) 値型はインタフェース契約を提供しないが,その関連するボックス化型は提供する。 

3) 値型は継承されない。むしろ,クラス定義の中で指定された基底型は,ボックス化型の基底型を定

義する。 

4) ボックス化型の基底型は,フィールドをもってはならない。 

5) オブジェクト型とは違い,値型のインスタンスは,インスタンスが生成されるときに呼び出される

構築子を要求しない。代わりに,正当性検証規則が,正当性検証可能コードがインスタンスを0に

(オブジェクトについてはnullに)初期化することを要求する。 

8.9.8 

型の継承 

型の継承は,派生した型が基底型の型契約のすべての提供を保証することを示すもう一つの方法とする。

さらに,派生した型は,通常,追加的な機能又は特殊化された振る舞いを提供する。型は,基底型の型契

約を実装することによって,基底型から継承される。一つのインタフェース型は,0個以上の他のインタ

フェースを実装する。値型は継承されない。ただし,関連するボックス化型はオブジェクト型であって,

他の型から継承される。 

派生したクラス型は,その基底型の提供するインタフェース契約,クラス契約,イベント契約,メソッ

ド契約及び特性契約のすべてを提供しなければならない。さらに,基底型が定義する格納域のすべては,

派生型でも定義される。継承の規則は,基底型の値を用いて動作するようにコンパイルされたコードが,

派生型の値を渡されたときでも動作することを保証する。このために,派生型は,基底型の実装をも継承

する。派生型は,この実装を拡張,上書き及び/又は隠ぺいできる。 

8.9.9 

オブジェクト型の継承 

System.Objectが他のオブジェクト型から継承されないという唯一の例外を除いて,すべてのオブジ

background image

46 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

ェクト型は,明示的又は暗黙的のいずれかで,ただ一つの他のオブジェクト型を提供する(すなわち,そ

のオブジェクト型から継承される。)と宣言しなければならない。継承関係のグラフは,その基底を

System.Objectとする一つの根をもつ木を形成しなければならない。すなわち,すべてのオブジェクト

型は,結局のところ,型System.Objectから継承される。 

総称型の導入によって,正確な定義を与えることがより難しくなる。第2章を参照。 

オブジェクト型は,それを封印された型,すなわち,封印型と宣言することによって,それを基底型と

して用いてはならない(それを継承してはならない)と宣言する。 

CLS規則23 System.Objectは,CLS合致とする。あらゆる他のCLS合致クラスは,一つのCLS合

致クラスから継承されなければならない。 

配列はオブジェクト型であって,それ自体,他のオブジェクト型から継承される。配列オブジェクト型

はVESによって操作されるから,配列の継承は固定される(8.9.1参照)。 

8.9.10 値型の継承 

値型は,そのボックス化されていない形式では,いかなる型からも継承されない。ボックス化された値

型は,それが列挙型でない限り,System.ValueTypeから直接に継承されなければならない。列挙型で

ある場合には,System.Enumから継承されなければならない。ボックス化された値型は,封印されなけ

ればならない。 

論理的に,値型に対応するボックス化型は,次のとおりになる。 

− オブジェクト型である。 

− どのオブジェクト型がその基底型になるかを,すなわち,それが継承するオブジェクト型を指定する。 

− フィールドが定義されていない基底型をもつ。 

− 値断片化の複雑さの処理を避けるために封印される。 

ここでより多くの規則を規定することによって,面倒な妥協的機能を用いることなく,より効率的な実

装が可能になる。 

8.9.11 インタフェース型の継承 

インタフェース型は,一つ以上の他のインタフェース型の実装を要求できる。インタフェース型の提供

を実装する型は,そのインタフェースによって指定されるあらゆる要求されるインタフェースの提供をも

実装しなければならない。これは,オブジェクト型の継承と次の二つの点で異なっている。 

− オブジェクト型は,一つの根をもつ木を構成するが,インタフェース型はそうではない。 

− オブジェクト型の継承は,どのようにして実装が継承されるのかを指定するが,要求されるインタフ

ェース型はそうではない。これは,インタフェースは実装を定義しないことによる。要求されるイン

タフェースは,実装するオブジェクト型が提供しなければならない追加的契約を指定する。 

後者の違いを明確にするために,一つのメソッドをもつインタフェースIFooを考える。それから派生

するインタフェースIBarは,IBarが提供するオブジェクト型がIFooも提供することを要求している。

IBarそれ自体がどのメソッドをもつかについては何もいっていない。 

8.10 メンバの継承 

オブジェクト型だけが実装を継承できる。したがって,オブジェクト型だけがメンバを継承できる(8.9.8

参照)。インタフェース型は,他のインタフェース型から派生できるが,メソッド契約を実装するための要

件だけを“継承”し,フィールドもメソッドの実装も継承しない。 

8.10.1 フィールドの継承 

47 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

派生オブジェクト型は,その基底オブジェクト型の静的でないフィールドのすべてを継承する。これは,

基底型のインスタンスが期待されるいずれの箇所でも,派生型のインスタンスを使用できるようにする。

これらのインスタンスの形状,すなわち,配置が,同じになる。静的フィールドは継承されない。フィー

ルドが存在するという理由だけでは,それを読んだり書いたりできることを意味しない。型の可視性,フ

ィールドのアクセス可能性及びフィールド定義のセキュリティ属性(8.5.3参照)が,フィールドが派生オ

ブジェクト型に対してアクセス可能かどうかを決定する。 

8.10.2 メソッドの継承 

派生オブジェクト型は,その基底オブジェクト型のインスタンスメソッド及び仮想メソッドのすべてを

継承する。構築子及び静的メソッドは継承しない。メソッドが存在するという理由だけでは,それを呼び

出せることを意味しない。参照しているコードで使われている型付けされた参照を通してアクセス可能と

なる。型の可視性,メソッドのアクセス可能性及びメソッド定義のセキュリティ属性(8.5.3参照)が,メ

ソッドが派生オブジェクト型に対してアクセス可能かどうかを決定する。 

派生オブジェクト型は,同じ名前,又は同じ名前及び同じ識別情報をもつ新しいメソッド定義を提供す

ることによって,その基底型の仮想でないメソッド(すなわち,静的メソッド又はインスタンスメソッド)

を隠ぺいできる。そうであっても,メソッドのアクセス可能性規則に従って,いずれかのメソッドを呼び

出すことができる。これは,メソッドを含む型がメソッド参照を限定することによる。 

仮想メソッドは,final(最終)と印付けできる。この場合,それらは,派生オブジェクト型の中で上

書きされてはならない。これによって,メソッドの実装が,最終の実装を供給する基底クラスの契約を提

供するあらゆるオブジェクトで,仮想呼出しによって,確実に利用可能になる。仮想メソッドが最終(final)

でない場合,仮想メソッドを上書きするためにセキュリティ許可を要求することが可能であって,その結

果として,実装を提供する能力を特定の許可をもつクラスに制限できる。派生クラスが仮想メソッドを上

書きする場合,そのクラスは,その仮想メソッドのために新しいアクセス可能性を指定できる。しかし,

派生クラスにおけるアクセス可能性は,少なくとも,そのクラスが上書きしているメソッドに与えられる

アクセスと同じ程度のアクセスを許可しなければならない。8.5.3を参照。 

8.10.3 特性及びイベントの継承 

基本的に,特性及びイベントは,CLIを目標とするがVESそれ自体によって直接には支援されないツー

ルが使用することを意図しているメタデータの構成要素とする。そこで,名前の隠ぺい,継承などのため

の規則を決定するのは,ソース言語コンパイラ及び自己反映ライブラリ(第4章参照)の仕事とする。ソ

ースコンパイラは,イベント及び特性によって名前を付けられるメソッドに直接にアクセスするCILを生

成しなければならないが,イベント又は特性を生成してはならない。 

8.10.4 隠ぺい,上書き及び配置 

継承に関連して二つの異なる問題がある。一つめは,型が実装しなければならないのはどの契約か,す

なわち,型が提供しなければならないのはどのメンバ名及び識別情報かという問題である。二つめは,派

生型のインスタンスでその基底型のインスタンスを置換することができるための,インスタンスの配置で

ある。派生型の一部である静的でないフィールド及び仮想メソッドだけが,オブジェクトの配置に影響す

る。 

CTSは,基底型から可視な名前と,派生クラスにおける配置スロットの共有との両方に関する独立な制

御を提供する。それら制御のうち,前者が隠ぺい,後者が上書きになる。名前による隠ぺい(hide by name)

又は名前及び識別情報による隠ぺい(hide by name-and-signature)のいずれかと印付けることによって制御

する。隠ぺいは,常に,メンバの種類に基づいて実行される。すなわち,派生フィールド名は,基底フィ

background image

48 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

ールド名を隠ぺいできるが,メソッド名,特性名及びイベント名を隠ぺいしない。派生メンバが名前によ

る隠ぺいと印付けられる場合,基底クラスの中の同じ名前をもつ同じ種類のメンバは,派生クラスの中で

は可視でない。メンバが名前及び識別情報による隠ぺいと印付けられる場合,フィールドに対しては,同

じ名前であって同じ型をもつ同じ種類のメンバだけが,メソッドに対しては,同じ名前であって同じ識別

情報をもつ同じ種類のメンバだけが,派生クラスから隠ぺいされる。隠ぺいのこれら二つの形式の間の違

いの実装は,完全に,ソース言語コンパイラ及び自己反映ライブラリによって提供される。VESそれ自体

には,何ら直接の影響はない。 

次に例を示す。 

class Base 

{ field  int32         A; 

  field  System.String A; 

  method int32         A(); 

  method int32         A(int32); 

class Derived inherits from Base 

{ field  int32 A; 

  hidebysig method int32 A(); 

型Derivedの中で使用可能なメンバ名を表3に示す。 

表3−メンバ名 

メンバの種類 

メンバの型又は識別情報 

メンバの名前 

Field 

int32 

Method 

() -> int32 

Method 

(int32) -> int32 

隠ぺいは型のすべてのメンバに適用されるが,上書きは,オブジェクトの配置を扱い,インスタンスフ

ィールド及び仮想メソッドだけに適用可能とする。CTSは,メンバ上書きの二つの形式,新規スロット(new 

slot)及び既存スロット期待(expect existing slot)を提供する。新規スロットと印付けられた派生型のメン

バは,常に,オブジェクトの配置の中で新規スロットを得て,そのオブジェクトの中で基底型のフィール

ド又はメソッドは,基底型の名前をメンバ及びその型又は識別情報の名前と結合する限定された参照を使

用することによって使用可能になることを保証する。既存スロット期待と印付けられた派生型のメンバは,

同じ種類(フィールド又はメソッド),同じ名前及び同じ型のメンバに対応するスロットを,それが基底型

で既に存在している場合には,再利用(すなわち,共有又は上書き)する。そのようなスロットが存在し

ない場合には,新しいスロットが割り付けられ使用される。 

型における名前及び型のオブジェクトの配置を決定するために使用する一般的なアルゴリズムは,おお

よそ,次による。 

− アクセス可能性規則は無視し,(名前による隠ぺい又は名前及び識別情報による隠ぺいの規則を使っ

て)継承された名前を平たん化する。 

− “既存スロット期待”と印付けられた新しいメンバそれぞれに対して,種類(すなわち,フィールド

49 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

又はメソッド),名前及び識別情報に関する厳密な一致が存在するかどうかを(すなわち,既存のスロ

ットの存在を)調べ,見つかった場合にはそのスロットを使用し,そうでない場合には新しいスロッ

トを割り付ける。 

− すべての新しいメンバに対してこれを行った後で,これらの新しいメンバ,その種類,名前及び識別

情報をこの型のメンバの一覧に追加する。 

− 最後に,名前による隠ぺい又は名前及び識別情報による隠ぺいの規則に基づいて新しいメンバに一致

する継承された名前を取り除く。 

8.11 メンバ定義 

オブジェクト型定義,インタフェース型定義及び値型定義は,メンバ定義を含むことができる。フィー

ルド定義は,値の下位構造を指定することによって型の値の表現を定義する。メソッド定義は,型の値に

関する演算及び型それ自体に関する演算(静的メソッド)を定義する。特性定義及びイベント定義は,オ

ブジェクト型についてだけ定義されなければならない。特性及びイベントは,名前の付いたイベント又は

特性の振る舞いを実装するアクセス操作子メソッド定義の名前の付いたグループを定義する。入れ子にな

った型宣言は,囲む側の型が有効範囲を与える名前をもち,囲む側の型のすべてのメンバへの完全なアク

セスをもつインスタンスを生成する型を定義する。 

型定義の種類に依存して,許されるメンバ定義には制限が存在する。 

8.11.1 メソッド定義 

メソッド定義は,名前,メソッド識別情報及び任意選択でメソッドの実装から構成される。メソッド識

別情報は,呼出し規約,メソッドへの仮引数の型及びメソッドの返却値型を定義する(8.6.1参照)。実装

は,メソッドが呼び出されたときに実行されるコードとする。値型又はオブジェクト型は,与えられた名

前及び識別情報のただ一つのメソッドを定義しなければならない。しかし,派生オブジェクト型は,その

基底オブジェクト型の同じ名前及び識別情報をもつメソッドをもつことができる(8.10.2及び8.10.4参照)。 

メソッドの名前の有効範囲は,その型になる(8.5.2参照)。メソッドには,アクセス可能性属性を与え

ることができる(8.5.3参照)。メソッドは,メソッド識別情報の仮引数型と代入互換な実引数をもつ場合

にだけ呼び出さなければならない。メソッドの返却値も,それが格納される格納域と代入互換でなければ

ならない。 

メソッドは,static(静的)と印付けできる。これは,メソッドが型の値の演算ではなくむしろ全体

として型と関連する演算であることを示す。staticと印の付いていないメソッドは,型の値の妥当な演

算を定義する。静的ではないメソッドを呼び出す場合,this又はthisポインタとして参照される型の

特定の値が暗黙の仮引数として渡される。 

メソッド実装を含まないメソッド定義は,abstract(抽象)と印付けられなければならない。インタ

フェース定義の静的ではないメソッドは,抽象的とする。抽象メソッド定義は,abstractと印を付けられた

オブジェクト型の中だけで許される。 

オブジェクト型における静的ではないメソッドは,virtual(仮想)として印付けできる。これは,派

生型の中で代替の実装が提供できることを示す。インタフェース定義の中のすべての静的ではないメソッ

ド定義は,仮想メソッドでなければならない。仮想メソッドは,final(最終)と印付けできる。これは,

派生オブジェクト型がメソッド実装を上書きすることを許されていないことを示す。 

メソッド定義は,総称メソッド定義として知られる機能として,総称仮引数をもつことができる。使用

するときには,総称メソッドの特定のインスタンス化が行われ,その時点で,総称仮引数は特定の総称実

引数に束縛される。総称メソッドは,非総称型のメンバとして定義できるし,総称型のメンバとしても定

background image

50 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

義できる。しかし,それ自体の型とは異なる総称仮引数(又は仮引数)によって仮引数化されることがあ

る。例えば,Stack<T>クラスは,総称メソッド S ConvertTo<S> () を含むかもしれない。ここで,

総称仮引数Sは,Stack<T>の総称仮引数Tと異なっている。 

8.11.2 フィールド定義 

フィールド定義は,名前及び格納域識別情報から構成される。格納域識別情報は,そのフィールドの型

及びアクセス制約を定義する(8.6.1参照)。値型又はオブジェクト型は,与えられた名前及び型のただ一

つのフィールドを定義しなければならない。しかし,派生オブジェクト型は,その基底オブジェクト型と

同じ名前及び型のフィールドをもつことができる(8.10.1及び8.10.4参照)。 

フィールドの名前の有効範囲は,その型になる(8.5.2参照)。フィールドは,アクセス可能性属性を与

えることができる(8.5.3参照)。フィールドは,そのフィールドの型と代入互換な値だけを格納しなけれ

ばならない(8.3.1参照)。 

フィールドは,static(静的)と印付けできる。これは,フィールドが型の値の一部ではなくむしろ全体

として型と関連する格納域であることを示す。静的フィールドのための格納域は,型がロードされたとき

に生成され,型が初期化されたときに初期化される。 

staticと印付けられていないフィールドは,値の下位構造を定義することによって型の値の表現を定義す

る(8.4.1参照)。そのようなフィールドのための格納域は,新しい値が構築されるときにいつでも,型の

すべての値(インスタンス)の内部に生成される。その格納域は,新しい値の構築中に初期化される。与

えられた名前の静的ではないフィールドは,常に,型のすべての値(インスタンス)の内部の同じ格納域

に位置付けられる。 

serializable(直列化可能)と印付けられたフィールドは,型の値の永続的状態の一部として直列化され

ることが望ましい。この規格は,規格適合処理系が直列化(又はその反対の直列化解除)を提供すること

を要求しないし,これらの操作を達成するかもしれない機構を規定しない。 

8.11.3 特性定義 

特性定義は,名前の付いた値及びその値にアクセスするメソッドを定義する。特性定義は,その値に関

するアクセス契約を定義する。したがって,特性定義は,どのアクセスメソッドが存在するか及びそのそ

れぞれのメソッド契約を指定する。特性契約の提供を宣言する型の実装は,その特性契約が要求するアク

セスメソッドを実装しなければならない。アクセスメソッドの実装は,値が取得され格納される方法を定

義する。 

特性定義は,常に,インタフェース定義又はクラス定義のいずれかの一部になる。特性定義の名前及び

値の有効範囲は,その特性定義を含む型になる。CTSは,特性を含むメソッド契約が,他のいかなるメソ

ッド契約をもつ場合と同様に,メソッド実装と一致することを要求する。特性と関連するCIL命令は存在

せず,単にメタデータとする。 

規約として,特性は,(特性の現在の値にアクセスするための)getterメソッド及び任意選択で(特性

の現在の値を修正するための)setterメソッドを定義する。CTSは,特性と関連するメソッドの集合,

それらメソッドの名前,又はその利用法についていかなる制限も課さない。 

CLS規則24 特性のgetter メソッド及びsetter メソッドを実装するメソッドは,メタデータの中

にSpecialNameと印付けられなければならない。 

CLS規則25 この規則は,もはや使用しない。 

注記 この規格の以前の版では,この規則は,“特性及びそのアクセス操作子のアクセス可能性は,同

background image

51 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

じでなければならない。”と規定されていた。この規則を取り除くことによって,例えば,

setterへのアクセスを制限しながらgetterへのアクセスを公開できる。 

CLS規則26 特性のアクセス操作子は,すべて静的,すべて仮想又はすべてインスタンスでなければな

らない。 

CLS規則27 特性の型は,getterの返却値型でなければならず,setterの最後の実引数の型でなけ

ればならない。特性の仮引数の型は,getterの仮引数の型でなければならず,setterの最後の仮引数

以外のすべての仮引数の型でなければならない。これらの型のすべては,CTS合致でなければならず,管

理下ポインタであってはならない。すなわち,参照によって渡されてはならない。 

CLS規則28 特性は,固有の名前付けパターンを守らなければならない(10.4参照)。CLS規則24で

参照されたSpecialName属性は,適切な名前比較においては無視されなければならず,識別子規則を守

らなければならない。特性は,getterメソッド,setterメソッド又は両方をもたなければならない。 

注記  

CLS(使用側) 適切な名前比較においてはSpecialNameビットを無視しなければならず,

識別子規則を守らなければならない。それ以外は,特性を定義するメソッドへの通常のアクセ

ス以外の直接の提供は必要ない。 

CLS(拡張側) 適切な名前比較においてはSpecialNameビットを無視しなければならず,

識別子規則を守らなければならない。それ以外は,特性を定義するメソッドへの通常のアクセ

ス以外の直接の提供は必要ない。特に,拡張側は,特性を定義できる必要はない。 

CLS(フレームワーク) すべてのCLS言語が特殊な構文を用いて特性にアクセスするわけ

ではないことを理解して設計を行わなければならない。 

8.11.4 イベント定義 

CTSは,それが特性を提供するのと正確に同じ方法でイベントを提供する(8.11.3参照)。しかし,規約

として決められているメソッドは異なっており,イベントの発火だけでなく,イベントへの登録及び登録

解除の手段を含む。 

CLS規則29 イベントを実装するメソッドは,メタデータの中にSpecialNameと印付けられなけれ

ばならない。 

CLS規則30 イベント及びそのアクセス操作子のアクセス可能性は,同一でなければならない。 

CLS規則31 イベントのためのaddメソッド及びremoveメソッドは,両方とも存在するか,両方と

も存在しないかのいずれかでなければならない。 

CLS規則32 イベントのためのaddメソッド及びremoveメソッドは,それぞれ,その型がイベント

の型を定義する一つの仮引数をもたなければならず,System.Delegateから派生していなければならな

い。 

CLS規則33 イベントは,固有の名前付けパターンを守らなければならない(10.4参照)。CLS規則29

で参照されたSpecialName属性は,適切な名前比較においては無視されなければならず,識別子規則を

守らなければならない。 

注記  

CLS(使用側) 適切な名前比較においてはSpecialNameビットを無視しなければならず,

識別子規則を守らなければならない。それ以外は,イベントを定義するメソッドへの通常のア

background image

52 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

クセス以外の直接の提供は必要ない。 

CLS(拡張側) 適切な名前比較においてはSpecialNameビットを無視しなければならず,

識別子規則を守らなければならない。それ以外は,イベントを定義するメソッドへの通常のア

クセス以外の直接の提供は必要ない。特に,拡張側は,イベントを定義できる必要はない。 

CLS(フレームワーク) すべてのCLS言語が特殊な構文を用いてイベントにアクセスする

わけではないことを理解しそれに基づいて設計を行わなければならない。 

8.11.5 入れ子になった型定義 

入れ子になった型定義は,一つの違いを除いて,最上位の型定義と同一とする。その違いとは,最上位

の型定義は可視性属性をもつが,入れ子になった型の可視性は,それを囲む側の型の可視性と同じとする

(8.5.3参照)。 

メタデータ 

注記 箇条9は,ここで導入され箇条11で繰り返されるCLS規則を除いて,参考情報だけを含む。

メタデータの書式は,第2章で規定する。 

値型及び参照型である新しい型は,メタデータで表現される型宣言を通じて,CTSに導入される。さら

に,メタデータは,CLIが,クラスを位置決めしてロードし,メモリにインスタンスを配置し,メソッド

呼出しを解決し,CILをプラットフォーム固有のコードに翻訳し,セキュリティを強制的に実行し,実行

時文脈境界を設定するために使用するすべての情報を表現するための構造化された方法とする。すべての

CLI PE/COFFモジュール(第2章参照)は,CLIを実現可能にする開発ツール又はコンパイラがモジュー

ルの中に生成するコンパクトなメタデータバイナリをもつ。 

CLIに対応するそれぞれの言語は,型及びメンバを宣言し,それらがインフラストラクチャのどのサー

ビスを要求するかを表現する属性を用いてそれらの型及びメンバを注記するために,それらの言語に適切

な構文を開示する。型の移入も言語に適切な方法で扱われ,開発者が目にする型の開示のためにメタデー

タを使用するのは,開発ツール又はコンパイラとする。 

典型的な構成部品又はアプリケーションの開発者は,CLIメタデータを生成し使用するための規則を意

識する必要はない。箇条9で概要を示す規則は,開発者がメタデータの構造を理解するのを助けることが

できるが,基本的には,ツール構築者及びコンパイラ作成者の関心事である。 

9.1 

構成部品及びアセンブリ 

それぞれのCLI構成部品は,その構成部品に固有な宣言,実装及び参照のためのメタデータをもつ。そ

の結果,構成部品固有なメタデータは,構成部品メタデータとして参照され,その結果生じる構成部品を

自己記述的という。COM又はCORBAといったオブジェクトモデルでは,この情報は,型ライブラリ,IDL

ファイル,DLLRegisterServer及び別々の書式の無数のカスタムファイルの結合によって表現され,実際の

実行ファイルとは分離されている。これと対照的に,メタデータは,CLI構成部品の基礎的な部分とする。 

CLI構成部品及びその他のファイルの集まりは,一緒にしてアセンブリに配備するようにパッケージ化

される。アセンブリは,後の箇条でより詳細に示す。アセンブリは,CLIでの再利用の基本的な単位とし

て役に立つ機能の論理的単位とする。アセンブリは,型のために名前の有効範囲を確立する。 

個々の構成部品の中で宣言され実装された型は,構成部品が参加するアセンブリを通じて他の実装が使

用するために移出されている。型へのすべての参照は,その型が使用されている文脈のアセンブリの同一

性によって有効範囲付けされる。CLIは,参照されたアセンブリを位置決めし,型参照の解決を要求する

53 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

ためのサービスを提供する。アプリケーションごとに分離した有効範囲を提供するのはこの機構とする。

アセンブリだけがその構成を制御する。 

9.2 

メタデータへのアクセス 

メタデータは,第2章で示されるとおりにファイル書式に直接にアクセスするか,又は自己反映ライブ

ラリを通じて,CLIモジュールに生成されそれから読まれる。第2章及び第3章で与えられる規定に基づ

き,開発中に,メタデータを含むCLIモジュールを正当性検証するツールを生成するのは可能である。 

クラスが実行時にロードされるとき,CLIローダは,メタデータをそれ自体のメモリ上のデータ構造に

送る。この構造は,CLI自己反映サービスを通じて閲覧できる。自己反映サービスは,コンパイラと同様

と考えることが望ましい。それは,継承されたメソッド及びフィールドについての情報を得るために継承

階層を自動的に巡回し,名前又は名前及び識別情報によって隠ぺいする規則をもち,メソッド及び特性の

継承についての規則をもつなどを行う。 

9.2.1 

メタデータトークン 

メタデータトークンは,実装依存の符号化機構とする。第2章では,どのメタデータトークンがCLI 

PE/COFFモジュールの様々な節に埋め込まれるかという方法を示す。メタデータトークンは,呼出し元で

メソッド呼出し及びフィールドアクセスを符号化するためにCIL及びプラットフォーム固有のコードに埋

め込まれる。トークンは,参照及びその参照を解決するためにそれが有効範囲付けされていた型について

のメタデータからの情報を取得するために,様々なインフラストラクチャサービスによって使用される。 

メタデータトークンは,(型宣言,メンバ宣言といった)メタデータオブジェクトの型付けされた識別子

とする。トークンを与えると,その型を決定でき,そのメタデータオブジェクトについて固有なメタデー

タ属性を取得できる。しかし,メタデータトークンは,永続的な識別子ではない。むしろ,それは特定の

メタデータバイナリに有効範囲を提供する。メタデータトークンは,メタデータのデータ構造内の添字と

して表現される。それゆえ,高速かつ直接的なアクセスができる。 

9.2.2 

メタデータの中のメンバ識別情報 

フィールド,仮引数,メソッド返却値及び特性を含むすべての格納域は,型をもち,その型の規定は,

メタデータ内にもつ。 

値型は,ビットの並びとして表現される値を記述する。参照型は,ビットの並びの格納域として表現さ

れる値を記述する。CLIは,組込み型の明示的な集合を提供し,組込み型のそれぞれは,値型又は参照型

のいずれかとして既定の実行時形式をもつ。メタデータのAPIは,追加的な型を宣言するために用いるこ

とができ,変数の型規定の一部は,その型が実行時にどの形式(値又は参照)をとるのがよいかだけでな

く型の同一性も符号化する。 

符号化された型を表現するメタデータトークンは,型を受諾するCIL命令(newobj,newarray,

ldtokenなど)に渡される。第3章のCIL命令集合規定を参照。 

これらの符号化された型メタデータトークンは,メンバ識別情報の中にも埋め込まれる。フィールドア

クセス及びメソッド呼出しの実行時結合を最適化するために,フィールド及びメソッドに関連する型識別

情報及び格納域識別情報は,メタデータの中のメンバ識別情報に符号化される。メンバ識別情報は,メン

バへの参照が成功するか又は失敗するかどうかを決定するために使用する契約情報のすべてを具現化する。 

9.3 

管理外コード 

CLI管理下コードから管理外コードへデータを渡すのは,可能とする。これは,管理下コードから管理

外コードへの遷移を常に含む。その中には,何らかの実行時コストが発生するが,データは,コピーなし

に転送できる場合が多い。データが再書式化されなければならない場合,VESは,既定の振る舞いの合理

54 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

的な規定を提供するが,組換え(すなわち,再書式化されたコピー動作)の他の形式を明示的に要求する

ためにメタデータを使用できる。メタデータは,実装固有の既存機構を通じての管理外コードへのアクセ

スも許可する。 

9.4 

メソッド実装メタデータ 

実装が現在のCLIモジュールで供給されているメソッドそれぞれのために,ツール又はコンパイラは,

CILからプラットフォーム固有のコードへのコンパイラ,CLIローダ及び他の情報サービスが使用する情

報を生成する。この情報は,次を含む。 

− コードが,管理下又は管理外かどうか。 

− 実装が,そのCPUに固有なコード又はCILかどうか。すべてのCILコードは管理下であることに注

意する。 

− 現在のモジュールの中での,メソッド本体が置かれているモジュールファイルの先頭からの相対的な

アドレスとしての位置。これを,相対仮想アドレス又はRVAという。他の方法として,RVAは0に

符号化し,メソッド実装が見いだされる格納域をインフラストラクチャに示すために他のメタデータ

を使用することもある。これは,次を含む。 

− メソッド実装は,この規格以外で記述される実装固有の手段によって位置決めされる。 

− 移入されている大域静的メソッドを通じて呼出しを転送する。 

9.5 

クラスの配置 

一般に,CLIローダは,CTSの規則と矛盾しないように,それが選択する方法でクラスのインスタンス

を自由に配置する。しかし,ツール又はコンパイラが,より多くの制御を配置に必要とする場合がある。

メタデータでは,クラスは,その配置規則が次のいずれであるかを示す属性を用いて印付けられる。 

− 自動配置(autolayout) autolayoutと印付けられたクラスは,ローダが整合すると判断する方法で

クラスを自由に配置することを示す。指定されるかもしれない配置情報は,無視される。この自動配

置を,省略時の値とする。 

− 順次配置(sequentiallayout) sequentiallayoutと印付けられたクラスは,生成されたフィールド

の順番を保存するようにローダを導くが,それ以外の特定のオフセットは,フィールドのCLI型に基

づいて計算される。これらは,明示的なオフセット,詰物及び/又は境界調整の情報によってずらす

ことができる。 

− 明示配置(explicitlayout) explicitlayoutと印付けられたクラスは,ローダに,フィールドの列

を無視し,フィールドオフセット及び/又は全体的なクラスの大きさ若しくは境界調整の形式で提供

される明示的な配置規則を使用するようにする。第2章に示すように,正当な配置には制限が存在す

る。 

クラスの全体の大きさを指定することも可能とする。これによって,ツール又はコンパイラが,型の大

きさだけが供給されている値型指定を生成できる。これは,(32ビット整数といった)CLI組込み型の宣

言に役立つ。構造化された値型のメンバのデータ型がCLIメタデータの中に表現をもたない場合(例えば,

C++ビットフィールドなど)にも役に立つ。後者の場合,ツール又はコンパイラが配置を制御し,CLIが

詳細を知る又は配置にかかわる必要がない限り,これで十分になる。これは,VESはビットを移動するこ

とはできるが,機械にまたがって組換えはできないことを意味することに注意する。生成を行うツール又

はコンパイラが,組換えを処理する必要がある。 

任意選択で,開発者は,クラスの詰める大きさを指定できる。これは,それほど多く使用される配置情

報ではないが,開発者がフィールドの境界調整を制御するのを可能にする。それは,本質的に境界調整指

55 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

定ではなく,むしろ,すべての境界調整に上限を設ける修飾子としてのサービスになる。典型的な値は,1,

2,4,8 又は 16である。総称型は,explicitlayoutと印付けしてはならない。 

クラス配置属性の完全な規定については,第4章のSystem.Runtime.InteropServicesにおけるク

ラス群を参照。 

9.6 

アセンブリ,すなわち,型のための名前の有効範囲 

アセンブリは,機能のまとまりのある集合を配布する目的で一緒に作動するために組み立てられた資源

の集まりとする。アセンブリは,そのまとまりを確実にするのに必要な規則のすべてをもつ。それは,CLI

において資源にアクセスする単位とする。 

外部的には,アセンブリは,型を含む移出されている資源の集まりになる。資源は,名前によって移出

されている。内部的には,アセンブリは,公開(移出されている)資源及び私的(アセンブリ内部の)資

源の集まりになる。どの資源をアセンブリの外部に移出しているか,どの資源を現在のアセンブリの有効

範囲の内部だけでアクセス可能とするかを決定するのは,アセンブリとする。資源への参照,公開又は私

的が資源を実装するビットに対応付けられる方法を制御するのは,アセンブリとする。特に型に対して,

アセンブリは,実行時構成情報を供給できる。CLIモジュールは,型の宣言及び実装のパッケージ化した

ものと考えることができる。ここで,パッケージ化の決定は,アセンブリのクライアントに影響を与える

ことなく,そのパッケージ化する対象範囲の中で変更できる。 

型の同一性は,そのアセンブリの有効範囲及びその宣言された名前による。二つの異なるアセンブリの

中で同一的に定義された型は,二つの異なる型と考えられる。 

アセンブリ依存性 アセンブリは,他のアセンブリに依存できる。これは,一つのアセンブリの有効範

囲の中の実装が,他のアセンブリの中に有効範囲をもつ場合,又はそれが所有する資源を参照する場合に

発生する。 

− 他のアセンブリへのすべての参照は,現在のアセンブリの有効範囲の制御の下に解決される。これに

よって,アセンブリは,他のアセンブリへの参照がその参照されるアセンブリの特定の版(又は他の

特徴)へと対応付けられる方法を制御する可能性をもつ。ただし,参照される資源が実装に対して解

決される方法に関しては,その対象となるアセンブリが独立の制御をもっている。 

− 特定の実装がその中で実行されるアセンブリ有効範囲を決定するのは,常に可能とする。そのアセン

ブリ有効範囲から発生するすべての要求は,その有効範囲に対して相対的に解決される。 

配備の観点からは,アセンブリは,それが参照する他のアセンブリがその配備環境の中で使用可能と仮

定して,それ自体,配備できる。その依存するアセンブリと一緒に配備できる。 

内容目録 すべてのアセンブリは,アセンブリを構成するファイル,移出されている型及びアセンブリ

の内部で型参照を解決するために要求される他のアセンブリ,を宣言する内容目録をもつ。CLI構成部品

がそのCLI構成部品の中のメタデータを通じて自己記述的であるように,アセンブリは,内容目録を通じ

て自己記述的とする。一つのファイルがアセンブリを形成する場合,そのファイルは,アセンブリの中で

定義される型を記述するメタデータ及びアセンブリそれ自体を記述するメタデータの両方を含む。アセン

ブリが,メタデータをもつ二つ以上のファイルを含む場合,それぞれのファイルは,存在する場合にはそ

のファイルの中で定義される型を記述し,さらに,これらのファイルの一つが,そのアセンブリを記述す

るメタデータ(他のファイルの名前,その暗号レベルの精度のハッシュ及びアセンブリの外部に移出して

いる型を含む。)も含む。 

アプリケーション アセンブリは,アプリケーションごとに分離した意味を導入する。アプリケーショ

ンは,単に,新しいアプリケーション領域の生成を引き起こす(又はブラウザのようなホスト環境に生成

background image

56 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

を引き起こさせる)外部入口点をもつアセンブリとする。この入口点は,実効的に,要求の呼出し及び解

決木の根となる。アプリケーションの中には,一つの自己完結したアセンブリもあるが,それが必要とす

る資源を提供する他のアセンブリが利用可能であることを要求するものもある。いずれの場合も,ロード

されるモジュールに対して要求が解決されるとき,そのモジュールは,その要求が発生した同じアプリケ

ーション領域へとロードされる。アプリケーション領域を通じて,アプリケーションを監視又は停止する

ことができる。 

注記 型への参照は,常に,その参照が解決されるのが望ましいアセンブリ有効範囲を用いて,型名

を限定する。すなわち,アセンブリは,利用可能な資源の名前の有効範囲を確立する。しかし,

個々のモジュールと参照されるアセンブリとの間の関係を確立するのではなく,すべての参照

は,現在のアセンブリを通じて解決される。これによって,それぞれのアセンブリが,参照を

解決する方法の絶対的な制御をもつことが可能になる(第2章参照)。 

9.7 

メタデータの拡張性 

CLIメタデータは,拡張可能とする。これを重要とするのには,次の三つの理由がある。 

− 共通言語規定(Common Language Specification,CLS)は,言語及びツールが,よりよい言語統合のた

めに一様な方法で提供するのを合意した規約のための規定とする。CLSは,CTSモデルの一部を制約

し,CLSは,CTSの上位の層を成すより高位の抽象を導入する。ツールが使用するこれら種類の開発

時における抽象化をメタデータによって捕そく(捉)できることが重要である。ただし,これらの抽

象化は,CLIによって明示的には認識されていないし提供されていないことに注意する。 

− CLIでもCLSの言語抽象でもない言語固有の抽象をメタデータで表現できることが望ましい。例えば,

C++のような言語が,コンパイルされたモジュールによって移出されている型,メソッド及びデータ

メンバを使用するために,別々のヘッダ又はIDLファイルを,長い年月にわたって,必要としないよ

うにできることが望ましい。 

− メンバ識別情報において,言語固有の多重定義で使用される型及び型修飾子を符号化できることが望

ましい。例えば,基礎となる型int32にint及びlongの両方を対応付ける32ビット機械上でさえ

も,C++が,intをlongから区別できるようにする。 

この拡張可能性は,次の形式になる。 

− すべてのメタデータオブジェクトは,カスタム属性をもつことができ,メタデータAPIは,カスタム

属性を宣言し,数え上げ,取得する方法を提供する。カスタム属性は,単純名によって識別できるが,

この場合,値符号化は不透明であって,それを定義した特定のツール,言語又はサービスにだけ知ら

れているとする。カスタム属性は,型参照によっても識別できる。この場合には,その属性の構造は,

(その型で宣言されたデータメンバを通じて)自己記述的であって,CLI自己反映サービスを含むあ

らゆるツールがその値符号化を閲覧できる。 

CLS規則34 CLSは,カスタム属性の符号化の部分集合だけを許す。これらの符号化で出現しなけれ

ばならないものは,System.Type,System.String,System.Char,System.Boolean,System.Byte,

System.Int16,System.Int32,System.Int64,System.Single,System.Double及びCLS合

致の基底整数型に基づく列挙型だけとする(第4章参照)。 

注記  

CLS(使用側) 制限された方式を使って符号化された属性を読むことができる。 

CLS(拡張側) CLS使用側のためのすべての要件を満たし,新しいクラス及び新しい属性を

background image

57 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

編集できなければならない。既存の属性クラスに基づく属性を生成されたあらゆるメタデータ

に添付できる。System.AttributeUsageAttributeのための規則を実装する(第4章参照)。 

CLS(フレームワーク) CLS規則の範囲内であって,System.AttributeUsageAttribute

のために規定された規約に従って符号化された属性だけを外部に開示する。 

− CTS型拡張可能性に加えて,カスタム修飾子をメンバ識別情報の中に生成できる(型,第2章参照)。

CLIは,メソッドの結合のためだけでなく,多重定義及び隠ぺいの目的でこれらの修飾子を大切にし,

言語固有の意味を強制はしない。これらの修飾子は,メソッドの返却値型若しくは仮引数又はフィー

ルドの型を参照できる。それらは2種類になる。一つは,正しく使用するためにそのメンバを使うす

べてが理解しなければならない必す(須)修飾子であって,もう一つは,修飾子が理解されない場合

には無視できる任意選択修飾子とする。 

CLS規則35 CLSは,公開の可視である必す(須)修飾子(modreq,第2章参照)を許さないが,CLS

が理解しない任意選択修飾子(modopt,第2章参照)は許す。 

注記  

CLS(使用側) 任意選択修飾子を含むメタデータを読み,それらを含む識別情報を正しくコ

ピーできなければならない。型一致及び多重定義解決ではこれらの修飾子を無視できる。任意

選択修飾子を無視した場合にあいまい(曖昧)になる型,又は必す(須)修飾子を使用する型

を無視できる。 

CLS(拡張側) 任意選択修飾子を含む識別情報をもつ継承されたメソッドのための上書きを

編集できなければならない。その結果として,拡張側は,それが移入するメタデータからそれ

ら修飾子をコピーできなければならない。必す(須)修飾子を提供するという要件も,その識

別情報の中にあらゆる種類の修飾子をもつ新しいメソッドを編集するという要件も存在しな

い。 

CLS(フレームワーク) 必す(須)修飾子がCLS合致ではないと印付けられていない場合,

外部に可視な識別情報の中で必す(須)修飾子を用いてはならない。一つのクラスの二つのメ

ンバが,それらの識別情報の中での任意選択修飾子の使用だけで異なっており,それらの一つ

だけがCLS合致と印付けられているわけではない場合,それらの二つのメンバを開示してはな

らない。 

9.8 

大域的,移入及び移出 

CTSは,大域的に静的という概念をもたない。すべての静的なものは,特定のクラスと関連している。

それにもかかわらず,メタデータは,PE/COFFファイルの中に直接に格納され,その相対仮想アドレスに

よってアクセスされる静的データに依存する言語を,支援するように設計されている。さらに,管理下デ

ータ及び管理下関数へのアクセスは,完全にメタデータそれ自体を通じて仲介される一方で,メタデータ

は,管理外データ及び管理外コードにアクセスする機構を提供する。 

CLS規則36 大域的に静的なフィールド及びメソッドは,CLS合致ではない。 

注記  

CLS(使用側) 大域的に静的なフィールド又はメソッドを支援する必要はない。 

CLS(拡張側) 大域的に静的なフィールド又はメソッドを編集する必要はない。 

CLS(フレームワーク) 大域的に静的なフィールド又はメソッドを定義してはならない。 

58 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

9.9 

有効範囲付けされた静的な関数又はデータメンバ 

CTSは,ファイル又は関数に有効範囲付けされた静的な関数又はデータメンバを含まない。しかし,コ

ンパイラは,有効範囲付けされた関数又はデータメンバのためにCILの中にメタデータトークンを生成す

ることが必要となる場合がある。メンバが宣言されており,コンパイラがすべてのアクセス規則の強制実

行を保証するPE/COFFファイルの外部で,メタデータは,そのメンバが決して可視でなくアクセス可能で

ないとするように,メンバが印付けされることを許す。 

10 共通言語仕様のための名前及び型の規則 

10.1 識別子 

大文字と小文字とを区別する言語又は大文字と小文字とを区別しない言語のいずれも,CLSを提供でき

る。この規則は他の言語に開示される項目にだけ適用されるから,アセンブリから移出されない非公開メ

ンバ又は非公開型には,それぞれの言語が選択した任意の名前を利用できる。しかし,相互運用に関する

制限が幾つか存在する。 

ツールに対して大文字と小文字とを区別する言語に十分に対応できるようにさせるには,識別子の大文

字と小文字とを正確に維持することが重要である。同時に,Unicodeで符号化された非英語を処理する場

合,結合文字を含んだ正確に同じ識別子を表現する方法が複数あり得る。CLSは,その識別子が適切な

Unicode標準の制限に従い,正規形式Cで永続化することを要求する。この正規形式Cは大文字と小文字

との違いを保持するが,結合文字を標準的な表現に強制する(8.5.1 CLS規則4参照)。 

同時に,外部可視名が大文字と小文字とを区別しない言語で利用された場合,他の外部可視名と衝突し

ないことは重要である。結果として,すべての識別子比較は正規形式KCを使ったCLS合致ツール内でな

されなければならない。この正規形式KCは,最初に文字をその大文字と小文字との正規形式に変換する

(8.5.1 CLS規則4参照)。 

CLS合致の言語のコンパイラが,CLS合致でない言語との相互運用性を提供する場合,CLS合致の言語

のコンパイラは,CTS及びVESが符号位置(バイト単位)の比較を使ってすべての比較を行うことを承知

していなければならない。すなわち,CLSが永続化された識別子に対して正規形式Cであることを要求し

ているにもかかわらず,CLS合致でない識別子の参照は,そのCLS合致でない言語が利用すると選択した

どんな符号化でも,それらを用いて永続化されなければならない。これは,言語設計上の課題であり,こ

れを正確にどのように扱わなければならないかはCTS又はCLSの範ちゅう(疇)にない。 

10.2 多重定義 

注記 CTSは継承,オブジェクト配置,名前の隠ぺい及び仮想メソッドの上書きについて記述する一

方,多重定義について何も記述していない。これは驚くべきことであるが,多重定義はCTSを

対象とするコンパイラですべて扱うものであり,型システム自身が扱うものではないという事

実からそうなっている。メタデータでは,型及び型メンバのすべての参照は完全に解決され,

意図された正確な識別情報を含む。どのプログラム言語も型付けに対する規則を独自にもち,

VESはそれらの規則を表現するための手段を提供していないから,この選択がなされた。 

CTSの規則によれば,種類(フィールド,メソッドなど),又は,識別情報が異なれば,同じ名前を同

じ有効範囲に複数定義することができる。CLSはメソッドの多重定義に対してより強力な制約を課してい

る。単一の有効範囲内で,与えられた名前は,次のいずれかが異なるように提供された複数のメソッドを

参照できる。 

− 仮引数の個数 

background image

59 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

− 任意の仮引数の型 

識別情報には多くの情報を含んでいるが,CLS合致の言語は,付加情報だけが異なるクラスを生成又は

消費する必要はないことに注意する(識別情報に載る情報の完全なリストは第2章を参照)。 

− 呼出し規約 

− カスタム修飾子 

− 返却型 

− 仮引数が値渡し又は参照渡しの区別 

この規則には一つの例外がある。10.3.3に記述されている特殊な名前op̲Implicit及びop̲Explicit

は,それらの返却値だけが異なるメソッドを提供できる。これらは特別に印付けられ,演算子多重定義を

扱わないコンパイラは,これらを無視できる。 

特性は,型(すなわち,それらのgetterメソッドの返却型)によって多重定義されてはならないが,

添字の個数又は型(すなわち,それらの取得メソッドの仮引数の個数又は型)が異なる特性は多重定義で

きる。特性に対する多重定義の規則は,メソッドの多重定義規則と同一とする。 

CLS規則37 特性及びメソッドだけを多重定義できる。 

CLS規則38 特性及びメソッドは,それらの仮引数の個数及び型にだけ基づいて多重定義できる。ただ

し,op̲Implicit及びop̲Explicitという名前の変換演算子は,それらの返却型に基づいても多重定

義できる。 

注記  

CLS(使用側) 特性及びメソッドだけが多重定義されるという仮定ができると,演算子多重

定義に対する特殊な構文が提供されていなければ,返却型に基づく多重定義を扱う必要がない。

返却値による多重定義を扱わないならば,その機能はCLS合致のフレームワークによる他の方

法で提供されなければならないから,op̲Implicit及びop̲Explicitを無視できる。使用

側は,どんなあいまい(曖昧)さも避けるために,名前による隠ぺい(蔽)規則並びに,識別

情報及び名前による隠ぺい(蔽)規則(8.10.4参照)を最初に適用しなければならない。 

CLS(拡張側) ここで規定された以上に多重定義の作成を許可してはならない。演算子多重

定義を扱う必要性は全くないから,返却値による多重定義を完全に扱わないようにすることも

できる。 

CLS(フレームワーク) ここで規定した以外に多重定義を公に開示してはならない。フレー

ムワーク作成者は,オブジェクト指向言語を含む多くのプログラム言語では多重定義を扱わず,

名前変換された名前を通して多重定義されたメソッド又は特性を開示することに気に留めてお

かなければならない。ほとんどの言語は,演算子多重定義も返却型による多重定義も扱わない。

そのため,op̲Implicit及びop̲Explicitは,常に,同じ機能を提供する何らかの代替方

法で補強しなければならない。 

注記 任意のクラスCにおいて可視な名前は,そのクラス及びその基底クラスで可視である。結果と

して,MethodImpls(2章参照)を介して実装されただけのクラスCで実装されたインタフェー

スのメソッド名は,クラスCで可視ではない。インタフェースIで可視な名前は,このインタ

フェースで直接定義された名前だけから構成される。その結果,インタフェースIが実装を要

求している他のインタフェースからのメソッド名は,インタフェースIから可視ではない。 

10.3 演算子多重定義 

background image

60 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

CLS合致の使用側ツール及び拡張側ツールには,演算子多重定義を可能としなくてもよい。CLS合致の

使用側ツール及び拡張側ツールは,これらのメソッドを呼び出す特殊な機構を提供する必要もない。 

注記 この話題は,次の事項が可能なように,CLSによって取り組まれている。 

− 演算子多重定義を提供する言語は,他の言語が理解できる方法で,その規則を記載する。 

− 演算子多重定義を提供しない言語は,特殊な構文を追加せずに,依然として基本となる機能

にアクセスする。 

演算子多重定義は,それらは利用者の名前空間と衝突することがないように,次に規定された名前の使

用及びメタデータ(SpecialName)内の特殊なビットの設定によって記述される。CLS合致の生産側ツ

ールは,このビットを設定するための何らかの手段を提供しなければならない。これらの名前が使われて

いるならば,それらはここで記載した意味規則を正確にもたなければならない。 

10.3.1 単項演算子 

単項演算子は一つの実引数を取り,それに対する何らかの演算を実行し,その結果を返却する。単項演

算子は,その一つの演算項の型を定義したクラスの静的メソッドとして表現される。表4 単項演算子名

に,定義済みの名前を示す。 

表4−単項演算子名 

名前 

JIS X 3014 C++演算子記号(この欄は参考とする。) 

op̲Decrement 

-- と類似1) 

op̲Increment 

++ と類似1) 

op̲UnaryNegation 

-(単項) 

op̲UnaryPlus 

+(単項) 

op̲LogicalNot 

op̲True 2) 

未定義 

op̲False 2) 

未定義 

op̲AddressOf 

&(単項) 

op̲OnesComplement 

op̲PointerDereference 

*(単項) 

注1) 純粋なC++の観点から見ると,CLIでは,これらの関数を書かなければならない方法は,次の非常に重要な

点に関して異なる。C++では,これらのメソッドは,それらの演算対象を直接増加又は減少させなければな
らない。一方,CLIではそうしてはならない。代わりに,それらの演算対象を変更せずに,単に演算対象に
対して適切に1を加えた値又は1を減じた値を返す。演算対象は,++演算子又は-演算子に対するコードを
生成するコンパイラによって増加又は減少されなければならず,これらのメソッドの呼出しとは区別されな
ければならない。 

2) op̲True演算子及びop̲False演算子は,C++には存在しない。それらは,データベース言語で使われてい

るような三つの状態をもつBoolean型に対応するために提供される。 

10.3.2 2項演算子 

2項演算子は二つの実引数を取り,何らかの演算を実行し,一つの値を返却する。2項演算子は,二つの

演算対象の一つの型を定義したクラスの静的メソッドとして表現される。表1-5 2項演算子名に定義済み

の名前を示す。 

background image

61 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

表5−2項演算子名 

名前 

JIS X 3014 C++演算子記号(この欄は参考とする。) 

op̲Addition 

+(2項) 

op̲Subtraction 

-(2項) 

op̲Multiply 

*(2項) 

op̲Division 

op̲Modulus 

op̲ExclusiveOr 

op̲BitwiseAnd 

&(2項) 

op̲BitwiseOr 

op̲LogicalAnd 

&& 

op̲LogicalOr 

|| 

op̲Assign 

未定義(=と同じではない) 

op̲LeftShift 

<< 

op̲RightShift 

>> 

op̲SignedRightShift 

未定義 

op̲UnsignedRightShift 

未定義 

op̲Equality 

== 

op̲GreaterThan 

op̲LessThan 

op̲Inequality 

!= 

op̲GreaterThanOrEqual 

>= 

op̲LessThanOrEqual 

<= 

op̲UnsignedRightShiftAssignment 

未定義 

op̲MemberSelection 

-> 

op̲RightShiftAssignment 

>>= 

op̲MultiplicationAssignment 

*= 

op̲PointerToMemberSelection 

->* 

op̲SubtractionAssignment 

-= 

op̲ExclusiveOrAssignment 

^= 

op̲LeftShiftAssignment 

<<= 

op̲ModulusAssignment 

%= 

op̲AdditionAssignment 

+= 

op̲BitwiseAndAssignment 

&= 

op̲BitwiseOrAssignment 

|= 

op̲Comma 

, 

op̲DivisionAssignment 

/= 

10.3.3 変換演算子 

変換演算子は,ある型から別の型への変換を許可する単項演算とする。この演算子メソッドは,演算対

象の型又は返却型のいずれかの静的メソッドとして定義しなければならない。次に示す2種類の変換があ

る。 

− 暗黙の(拡大)強制型変換は,数の大きさ又は精度を失ってはならない。暗黙の強制型変換は,

op̲Implicitという名前のメソッドを使って提供されることを推奨する。 

− 明示的な(縮小)強制型変換は,数の大きさ又は精度を失うことができる。明示的な強制型変換は,

op̲Explicitという名前のメソッドを使って提供されることを推奨する。 

background image

62 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

注記 変換は,他の方法では生成できない機能を提供する。多くの言語は,特殊な構文による変換演

算子の使用を提供しない。したがって,CLSの規則は,同じ機能を代替機構で利用可能にする

ことを要求する。より一般的なToXxx(Xxxを変換後の型の名前とする。)及びFromYyy(Yyy

を変換前の型の名前とする。)という命名パターンの使用を推奨する。 

これらの演算は,その演算対象の型(いわゆる“From”変換。)のクラスに存在できる。したがって,

返却型だけが異なることになるから,CLSは特に,これら二つの演算子は,その返却型に基づいて多重定

義されることを許可する。しかし,すべてのCLS言語が特殊な構文で演算子を実装しているとは限らない

から,この形態の多重定義が使われるならば,CLSは,その言語が同じ機能を提供する代替手段を提供し

なければならないことも要求する。 

CLS規則39 op̲Implicit又はop̲Explicitのいずれかが提供されている場合,その強制型変換に

対する代替手法を提供しなければならない。 

注記  

CLS(使用側) 言語設計において必要に応じて,メソッド多重定義の選択及び自動強制型変

換の生成において,op̲Implicit及び/又はop̲Explicitの存在を使う。 

CLS(拡張側) 言語設計において必要に応じて,対応するop̲Implicit,op̲Explicit,

ToXxx及び/又はFromXxxメソッドを使って利用者定義の明示的又は暗黙の強制型変換演算

子を実装する。 

CLS(フレームワーク) 強制型変換演算が提供されている場合,それらはFromXxx及び

ToXxxとして提供されなければならず,更に,省略可能なop̲Implicit及びop̲Explicit

も提供しなければならない。CLSフレームワークは,これらの強制型変換演算を提供すること

が推奨される。 

10.4 命名パターン 

第6章も参照。 

CTSは,特性又はイベントの命名を定義しない一方,CLSは順守すべきパターンを規定する。 

イベント用: 

個々のイベントは,そのイベントの通知に使われる委譲型を選択又は定義することによって生成される。

そして,イベント名に基づく名前及び固定された識別情報をもつ三つのメソッドが生成される。次の例で

は,EventHandlerという名前の委譲型を使用するClickという名前のイベントを定義する。 

EventAdd,イベント用のハンドラを追加するために使われる 

        パターン: void add̲<EventName> (<DelegateType> handler) 

        例: void add̲Click (EventHandler handler); 

EventRemove,イベント用のハンドラを削除するために使われる 

        パターン: void remove̲<EventName> (<DelegateType> handler) 

        例: void remove̲Click (EventHandler handler); 

EventRaise,発生したイベントを通知するために使われる 

        パターン: void family raise̲<EventName> (Event e) 

特性用: 

個々の特性は,取得子から返却される型及び(もしあれば)取得子の仮引数の型を決定することによっ

て生成される。そして,特性及びこれらの型の名前に基づいた名前の二つのメソッドが生成される。次の

background image

63 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

例では,二つの特性を定義する。仮引数をもたずSystem.Stringを返却するName及びSystem.Object

の仮引数をもちSystem.Objectを返却するItemである。Itemは添字指定された特性と呼ばれ,それ

は引数をとることを意味し,そのうえ,添字をもつ配列であるかのように利用者に見せることができる。 

PropertyGet,特性の値を読み出すために使われる 

        パターン: <PropType> get̲<PropName> (<Indices>) 

        例: System.String get̲Name (); 

        例: System.Object get̲Item (System.Object key); 

PropertySet,特性の値を変更するために使われる 

        パターン: void set̲<PropName> (<Indices>, <PropType>) 

        例: void set̲Name (System.String name); 

        例: void set̲Item (System.Object key, System.Object value); 

10.5 例外 

CLIは例外処理モデルを提供する。例外処理は12.4.2で導入される。CLS合致のフレームワークは外部

可視例外を定義及び送出できるが,送出されるオブジェクトの型には制約がある。 

CLS規則40 送出されるオブジェクトは,System.Exception又はそれを継承した型でなければなら

ない。しかし,CLS合致のメソッドは,他の例外型が伝ぱ(播)しないようにすることを要求しない。 

注記  

CLS(使用側) 規定された型ではないオブジェクトの送出又は捕そく(捉)を扱う必要はな

い 

CLS(拡張側) System.Exception又はそれを継承した型のオブジェクトの送出を扱わな

ければならない。他の型のオブジェクトを送出する必要はない。 

CLS(フレームワーク) System.Exceptionでもそれを継承する型でもないオブジェクト

を外部に公開してはならない。 

10.6 カスタム属性 

言語間で一貫したカスタム属性の参照を提供することを言語に許可するために,基底クラスライブラリ

はCLSで定義された次の規則に従う。 

CLS規則41 属性はSystem.Attribute又はそれを継承した型でなければならない。 

注記  

CLS(使用側) 規定された型ではない属性を提供する必要はない。 

CLS(拡張側) カスタム属性の作成を提供しなければならない。 

CLS(フレームワーク) System.Attributeでもそれを継承した型でもない属性を外部に

公開してはならない。 

特定の属性クラスの使用は,その属性クラスに属性を置くことによって,様々な方法で制約を課すこと

ができる。System.AttributeUsageAttributeは,これらの制約を指定するために使われる。

System.AttributeUsageAttributeによる制約は次のとおりとする。 

− どんな種類の構築要素(型,メソッド,アセンブリなど)も,それらに適用される属性をもてる。既

定では,属性クラスのインスタンスは,任意の構築要素に適用できる。これは,

System.AttributeUsageAttributeのValidOn特性の値を設定することで指定される。組み合

64 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

わせることができる構成要素がある。 

− 属性クラスの複数インスタンスは,与えられた一部のメタデータに適用できる。既定では,任意の与

えられた属性クラスの一つのインスタンスだけが,単一メタデータ項目に適用できる。属性の

AllowMultiple特性は,要求値を指定するために使用される。 

− 型に適用されるとき,その属性を継承しない。既定では,型に付随した任意の属性は,その型から派

生する型に継承されることを推奨する。属性クラスの複数インスタンスが許可されている場合,その

継承は,上位クラスから継承された属性と,明示的に下位クラス型に適用される属性との和集合を実

行する。複数インスタンスが許可されていない場合,下部クラスに直接適用される型の属性が,上位

クラスによって供給される属性を上書きする。これは,System.AttributeUsageAttributeの

Inherited特性に要求値を設定することで指定される。 

注記 これらはCLS規則であり,CTS自身の一部ではないから,ツールには,任意の与えられたメタ

データ項目に適用する意図のあるカスタム属性を明示的に指定することを要求される。すなわ

ち,メタデータを生成するコンパイラ又はその他のツールは,AllowMultiple及びInherit

規則を実装しなければならない。CLIは自動的に属性を提供しない。CLIでの属性の利用は,

第2章でも規定される。 

10.7 総称型及び総称メソッド 

10.7.1から10.7.6において,総称型及び総称メソッドに対するCLS規則を規定する。 

10.7.1 入れ子になった型仮引数の再宣言 

CLS合致のフレームワークによって移出される任意の型で,それが総称型内に入れ子になった場合,そ

れを囲んでいる型の総称仮引数のすべてが,それらが宣言された位置と同じ位置に,その入れ子型の総称

仮引数として宣言する。(入れ子型は,新しい総称仮引数を導入することもできる。)したがって,総称型

内に入れ子になったCLS合致の任意の型は,それ自身,総称型とする。このように再宣言された総称仮引

数は,新しく導入された総称仮引数のどれよりも先行していなければならない。 

例 次のC#のソースコードを例として示す。 

public class A<T> { 

  public class B { } 

  public class C<U, V> { 

    public class D<W> { } 

  } 

public class X { 

  public class Y<T> { } 

これに対応するILAsmのコードは次のようになる。 

.class ... À1<T> ... {  

// T is introduced 

  .class ... nested ... B<T> ... { }  

// T is redeclared 

  .class ... nested ... C̀2<T,U,V> ... { 

// T is redeclared; U and 

V are introduced 

    .class ... nested ... D̀1<T,U,V,W> ... { } 

// T, U, and V are 

redeclared; W is introduced 

background image

65 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

  } 

.class ... X ... { 

  .class ... nested Ỳ1<T> ... { } 

// Nothing is 

redeclared; T is introduced 

総称仮引数の再宣言は,仮引数の位置の一致を基準にしており,仮引数の名前の一致を基準に

していない。再宣言される総称仮引数の名前は,再宣言されたものと同じ名前である必要はない。

例えば,次のようになる。 

.class ... À1<T> ... {  

// T is 

introduced 

  .class ... nested ... B<Q> ... { }  

// T is 

redeclared (as Q) 

  .class ... nested ... C̀2<T1,U,V> ... { 

// T is 

redeclared (as T1); U and V are introduced 

    .class ... nested ... D̀1<R1,R2,R3,W> ... { } 

// T1, U, and V 

are redeclared (as R1, R2, and R3); W is introduced 

  } 

したがって,CLS合致のフレームワークは,次の型を開示しなければならない。 

語い(彙)名 

総称仮引数の個数 

再宣言された総称仮引数 

導入された総称仮引数 

A<T> 

1 (T) 

1 T 

A<T>.B 

1 (T) 

1 T 

A<T>.C<U,V> 

3 (T,U,V) 

1 T 

2 U,V 

A<T>.C<U,V>.D<W> 

4 (T,U,V,W) 

3 T,U,V 

1 W 

X.Y<T> 

1 (T) 

1 T 

CLS規則42 入れ子型は,少なくとも囲んでいる型と同じ数の総称仮引数をもたなければならない。入

れ子型の総称仮引数は,囲んでいる型の総称仮引数の位置に対応する。 

注記  

CLS(使用側) この規則に反する型を利用する必要はない。 

CLS(拡張側) 利用側と同様。総称型内に入れ子になる型の定義を採用する拡張側は,外部

に対して可視な型に対してもこの規則に従わなければならない。 

CLS(フレームワーク) この規則に反する型を開示してはならない。 

10.7.2 型名及び項数符号化 

CLS合致の総称型名は,"名前[̀項数]"という形式で符号化される。ここで,[...]は抑音アクセント文字(ア

クサングラーブ)"̀"及び項数がともに省略可能であることを示す。符号化された名前は,次の規則に従う。 

1) 名前は,"̀"を含まないID(第2章参照)でなければならない。 

2) 項数は,ゼロ又は空白を先行させない符号なし十進数として指定する。 

background image

66 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

3) 通常の総称型に対する項数は,その型で宣言された型仮引数の個数とする。 

4) 入れ子になった総称型に対する項数は,新しく導入された型仮引数の個数とする。 

例 次のC#のソースコードを例として示す。 

public class A<T> { 

  public class B { } 

  public class C<U, V> { 

    public class D<W> { } 

  } 

public class X { 

  public class Y<T> { } 

これに対応するILAsmのコードは次のようになる。 

.class ... À1<T> ... {  

// T is introduced 

  .class ... nested ... B<T> ... { }  

// T is redeclared 

  .class ... nested ... C̀2<T,U,V> ... { 

// T is redeclared; U and 

V are introduced 

    .class ... nested ... D̀1<T,U,V,W> ... { } 

// T, U, and V are 

redeclared; W is introduced 

  } 

.class ... X ... { 

  .class ... nested Ỳ1<T> ... { } 

// Nothing is 

redeclared; T is introduced 

CLS合致のフレームワークは,次の型を開示しなければならない。 

語い(彙)名 

総称仮引数の個数 

再宣言された 

総称仮引数 

導入された 
総称仮引数 

符号化された 

メタデータ 

A<T> 

1 (T) 

1 T 

À1 

A<T>.B 

1 (T) 

1 T 

A<T>.C<U,V> 

3 (T,U,V) 

1 T 

2 U,V 

C̀2 

A<T>.C<U,V>.D<W> 

4 (T,U,V,W) 

3 T,U,V 

1 W 

D̀1 

X.Y<T> 

1 (T) 

1 T 

Ỳ1 

メタデータ内に符号化された型名は,それを囲んでいる型を明示的に言及しないが,CLI及び

自己反映型名文法は,次のような詳細情報を含む。 

background image

67 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

語い(彙)名 

符号化されたメタデータ 

CLI 

自己反映 

A<T> 

À1 

À1 

À1[T] 

A<T>.B 

À1/B 

À1+B[T] 

A<T>.C<U,V> 

C̀2 

À1/C̀2 

À1+C̀2[T,U,V] 

A<T>.C<U,V>.D<W> 

D̀1 

À1/C̀2/D̀1 À1+C̀2+D̀1[T,U,V,W] 

X.Y<T> 

Ỳ1 

X/Ỳ1 

X+Ỳ1[T] 

CLS規則43 総称型の名前は,入れ子でない型で宣言された型仮引数の個数,又は入れ子型で新たに宣

言された型仮引数の個数を,上で定義した規則で符号化する。 

注記  

CLS(使用側) この規則に反する型を利用する必要はない。 

CLS(拡張側) 利用側と同様。総称型の定義を採用する拡張側は,外部に対して可視な型に

対してもこの規則に従わなければならない。 

CLS(フレームワーク) この規則に反する型を開示してはならない。 

10.7.3 型制約再宣言 

CLSフレームワークは,総称型が,その基底クラス及び実装したすべてのインタフェースにおける総称

仮引数に存在する任意の制約を明示的に再宣言するということを保証しなければならない。CLS拡張側及

びCLS使用側は,満足させる必要がある制約の集合を決定するために,問題とされる特定の型を検査でき

ることが望ましい。 

CLS規則44 総称型は,基底型又はインタフェースに対する任意の制約が,総称型の制約を満足させる

ことを保障するのに十分な制約を再宣言しなければならない。 

注記  

CLS(使用側) この規則に反する型を利用する必要はない。制約を検査する利用側は,適用

可能な制約を決定するのにインスタンス化している型を見ることだけを必要とする。 

CLS(拡張側) 利用側と同様。総称型の定義を採用する拡張側は,この規則に従わなければ

ならない。 

CLS(フレームワーク) この規則に反する型を開示してはならない。 

10.7.4 制約型の制限事項 

CLS規則45 総称仮引数に対する制約として利用される型は,それら自身がCLS合致でなければなら

ない。 

注記  

CLS(使用側) この規則に反する型を利用する必要はない。 

CLS(拡張側) 利用側と同様。総称型の定義を採用する拡張側は,CLS合致を検査するとき,

この規則に従わなければならない。また,この規則に反する構文を提供する必要はない。 

CLS(フレームワーク) この規則に反する型を開示してはならない。 

10.7.5 フレームワーク及び入れ子型のアクセス可能性 

CLIの総称は,総称型宣言及びその総称型のすべてのインスタンス化を,同じアクセス可能性の有効範

68 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

囲をもつように扱う。しかし,言語がもつアクセス可能性規則は,これとは異なってもよい。ある言語は,

CLIのアクセス可能性モデルに従った選択をし,他の言語では,より限定的な事前インスタンス化モデル

を利用することができる。すべてのCLS言語で消費できるようにするには,CLSフレームワークは,保守

的な事前インスタンス化モデルのアクセス可能性を考慮して設計されなければならない。さらに,入れ子

型を公開したり,総称型の特定な別のインスタンス化を基にした限定公開メンバへのアクセスを要求した

りしてはならない。 

これは,ファミリアクセス可能性をもつ入れ子型を含んでいる識別情報に影響がある。開いた総称型は,

ファミリアクセス可能性をもつ入れ子の総称型の特定なインスタンス化を含んでいる識別情報をもつフィ

ールド又はメンバを開示してはならない。総称基底クラス又は総称基底インタフェースの特定のインスタ

ンス化を拡張している非総称型は,ファミリアクセス可能性をもつ入れ子の総称型の異なるインスタンス

化を含んでいる識別情報をもつフィールド又はメンバを開示してはならない。 

例 次のC#のソースコードを例として示す。 

public class C<T> { 

  protected class N { … } 

  protected void M1(C<int>.N n) { … } 

// Not CLS-compliant ‒ C<int>.N not accessible form within C<T> in all 

language 

  Protected void M2(C<T>.N n) { … } 

// CLS-compliant ‒ C<int>.N accessible inside C<T> 

public class D : C<long> { 

  protected void M3(C<int>.N n) { … } 

// Not CLS-compliant ‒ C<int>.N not accessible in D(extends C<long>) 

  protected void M4(C<long>.N n) { … } 

// CLS-compliant - C<long>.N is accessible in D(extends C<long>) 

これに対応するILAsmのコードは次のようになる。 

.class public ... C̀1<T> ... { 

  .class ... nested ... N<T> ... { } 

  .method family hidebysig instance void M1(class C̀1/N<int32> n) ... 

{ } 

  // Not CLS-compliant ‒ C<int>.N not accessible form within C<T> in 

all language 

  .method family hidebysig instance void M2(class C̀1/N<!0> n) ... { } 

  // CLS-compliant ‒ C<int>.N accessible inside C<T> 

.class public ... D extends class C̀1<int64> { 

  .method family hidebysig instance void M3(class C̀1/N<int32> n) ... 

{ } 

  // Not CLS-compliant ‒ C<int>.N not accessible in D(extends C<long>) 

background image

69 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

  .method family hidebysig instance void M4(class C̀1/N<int64> n) ... 

{ } 

  // CLS-compliant - C<long>.N is accessible in D(extends C<long>) 

CLS規則46 インスタンス化された総称型内の,入れ子型を含め,そのメンバの可視性及びアクセス可

能性は,その総称型宣言全体ではなく,特定のインスタンス化された総称型の有効範囲にあるとみなさな

ければならない。そのようにみなすことによって,CLSの可視性及びアクセス可能性の規則12を適用す

る。 

注記  

CLS(使用側) この規則に反する型を利用する必要はない。 

CLS(拡張側) CLS合致を決定するとき,アクセス可能性に対するより制約のある記法を使

用しなければならない。 

CLS(フレームワーク) この規則に反するメンバを開示してはならない。 

10.7.6 フレームワーク及び抽象メソッド又は仮想メソッド 

CLSフレームワークは,CLSの拡張側に,そのフレームワークを利用するために,総称メソッドの上書

き又は実装を要求するライブラリを開示してはならない。これは,仮想総称メソッド又は抽象総称メソッ

ドが合致でないことを暗に意味しない。むしろ,CLSフレームワークは,適切な既定の動作をもつ具体的

な実装も提供しなければならないことを意味する。 

CLS規則47 個々の抽象総称メソッド又は仮想総称メソッドには,既定の具体的な非抽象の実装が存在

しなければならない。 

注記  

CLS(使用側) 影響なし。 

CLS(拡張側) 総称メソッドを上書きする構文を提供する必要はない。 

CLS(フレームワーク) 適切な具体的な実装を提供することなしに,この規則に反する総称

メソッドを開示してはならない。 

11 共通言語仕様規則の集約 

この箇条で,参照用にCLS規則の完全な集合を集約した。これらの規則は,“外部可視”項目すなわち,

それら自身のアセンブリの外部に可視な型及び公開のアクセス可能性,ファミリアクセス可能性又は“フ

ァミリ又はアセンブリ”アクセス可能性をもつ型のメンバにだけ適用することを思い起こしてほしい。さ

らに,項目はSystem.CLSCompliantAttributeを使ってCLS合致であるか又は合致でないかを明示

的に印付けできる。CLS規則は,CLS合致と印付けされた項目にだけ適用する。 

1) CLS規則は,定義の行われるアセンブリの外部からアクセス可能又は可視である型の部分に適用さ

れる(7.3参照)。 

2) CLS合致でない型のメンバはCLS合致に印付けされてはならない(7.3.1参照)。 

3) ボックス化値は,CLS合致ではない(8.2.4参照)。 

4) アセンブリは,識別子の開始文字及び継続文字の集合を規定するUnicode Standard 3.0の技術文書15

70 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

の附属書7に従わなければならない。これは,http://www.unicode.org/unicode/reports/tr15/tr15-18.html

で入手できる。識別子は,Unicode正規化形式Cが定義する正規形式でなければならない。CLSの

目的に対して,二つの識別子は,(Unicodeのロケールを意識しない1対1小文字対応付けが規定す

るとおりに)それら識別子を小文字に対応付けたものが同じ場合に同じとする。すなわち,二つの

識別子がCLSにおいて異なっていると考えられる場合,それらは,単に大文字と小文字とが異なっ

ている以上に異なっている。しかし,継承された定義を上書きするときに,CLIは,元の宣言の正

確な符号化が使用されることを要求する(8.5.1参照)。 

5) CLS合致の有効範囲で導入されるすべての名前は,それら名前が同一であって多重定義によって解

決される場合を除いて,種類とは独立に異なっていなければならない。すなわち,CTSは,一つの

型が一つのメソッド及び一つのフィールドに対して同じ名前を使用することを許すが,CLSは許さ

ない(8.5.2参照)。 

6) CTSでは異なる識別情報は区別可能だが,CLSでは,フィールド及び入れ子になった型は,識別子

の比較だけによって異なっていなければならない。(識別子の比較によって)同じ名前をもつメソッ

ド,特性及びイベントは,単に返却値の型だけ以外によって異なっていなければならない。ただし,

CLS規則39で規定した場合を除く(8.5.2参照)。 

7) enumの基礎となる型は,組込みのCLS整数型でなければならない。フィールドの名前は,“value̲̲”

でなければならず,そのフィールドは,RTSpecialNameと印付けされなければならない(8.5.2参

照)。 

8) System.FlagsAttribute(第4章参照)カスタム属性が存在する又は存在しないによって示さ

れる二つの異なる種類のenumが存在する。一つは,名前付き整数値を表現し,もう一つは,名前

付きでない値を生成するために結合可能な名前付きビットフラグを表現する。enumの値は,指定

された値に制限されない(8.5.2参照)。 

9) enumのリテラル静的フィールド(8.6.1参照)は,enumそれ自体の型をもたなければならない(8.5.2

参照)。 

10) アクセス可能性は,継承されたメソッドを上書きしても変化してはならない。ただし,“ファミリ又

はアセンブリ”アクセス可能性をもつ異なるアセンブリから継承されたメソッドを上書きする場合

を除く。この場合,ファミリアクセス可能性になる(8.5.3.2参照)。 

11) 識別情報に出現するすべての型は,CLS合致でなければならない。インスタンス化された総称型を

構成するすべての型は,CLS合致でなければならない(8.6.1参照)。 

12) 型及びメンバの可視性及びアクセス可能性は,そのメンバそれ自体が可視であってアクセス可能な

ときにはいつでも,メンバの識別情報内の型が可視であってアクセス可能でなければならないとい

うようになっていなければならない。例えば,アセンブリの外部で可視である公開メソッドは,そ

のアセンブリ内でだけ可視な型の実引数をもっていてはならない。あらゆるメンバの識別情報の中

で使用されるインスタンス化された総称型を構成する型の可視性及びアクセス可能性は,そのメン

バ自体が可視及びアクセス可能なときはいつでも,可視及びアクセス可能でなければならない。例

えば,アセンブリの外で可視なメンバの識別情報の中に存在するインスタンス化された総称型は,

型がそのアセンブリ内部だけで可視な総称実引数をもってはならない(8.6.1参照)。 

13) リテラルであって静的な値は,フィールド初期化メタデータ(第2章参照)を用いて指定される。

CLS合致のリテラルは,そのリテラルと厳密に同じ型(又はそのリテラルがenumである場合は基

礎となる型)のフィールド初期化メタデータで指定される値をもたなければならない(8.6.1.2参照)。 

71 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

14) 型付けされた参照は,CLS合致ではない(8.6.1.3参照)。 

15) vararg制約はCLSの一部ではなく,CLSが提供する呼出し規約だけを標準の管理下呼出し規約と

する(8.6.1.5参照)。 

16) 配列は,CLS合致の型をもつ要素をもち,配列のすべての次元は,0の下限をもつ。項目が配列で

あるという事実及び配列の要素型だけが,多重定義を区別する目的で必要となる。多重定義が二つ

以上の配列型に基づいている場合,要素型は名前付きの型でなければならない(8.9.1参照)。 

17) 管理外ポインタ型は,CLS合致ではない(8.9.2参照)。 

18) CLS合致のインタフェースは,それを実装するために非CLS合致のメソッドの定義を要求してはな

らない(8.9.4参照)。 

19) CLS合致のインタフェースは,静的メソッドを定義してはならないし,フィールドを定義してもな

らない(8.9.4参照)。 

20) CLS合致のクラス,値型及びインタフェースは,CLS合致でないインタフェースの実装を要求して

はならない(8.9.6.4参照)。 

21) オブジェクト構築子は,継承されたインスタンスデータへのアクセスが発生する前に,その基底ク

ラスのクラス構築子を呼び出さなければならない。これは,値型には適用されない。値型は,構築

子をもつ必要はない(8.9.6.6参照)。 

22) オブジェクト構築子は,オブジェクトの生成の一部として以外では呼び出されてはならないし,オ

ブジェクトは,2回初期化されてはならない(8.9.6.6参照)。 

23) System.Objectは,CLS合致とする。あらゆる他のCLS合致クラスは,一つのCLS合致クラス

から継承されなければならない(8.9.9参照)。 

24) 特性のgetterメソッド及びsetterメソッドを実装するメソッドは,メタデータの中に

SpecialNameと印付けられなければならない(第2章及び8.11.3参照)。 

25) この規則は,もはや使用しない。 

注記 この規格の以前の版では,この規則は,“特性及びそのアクセス操作子のアクセス可能性は,

同じでなければならない。”と規定されていた。この規則を取り除くことによって,例えば,

setterへのアクセスを制限しながら,getterへのアクセスを公開できる。 

26) 特性及びそのアクセス操作子は,すべて静的,すべて仮想又はすべてインスタンスでなければなら

ない(8.11.3参照)。 

27) 特性の型は,getterの返却値型でなければならず,setterの最後の実引数の型でなければなら

ない。特性の仮引数の型は,getterの仮引数の型でなければならず,setterの最後の仮引数以

外のすべての仮引数の型でなければならない。これらの型のすべては,CTS合致でなければならず,

管理下ポインタであってはならない。すなわち,参照によって渡されてはならない(8.11.3参照)。 

28) 特性は,固有の名前付けパターンを守らなければならない(10.4参照)。CLS規則24で参照された

SpecialName属性は,適切な名前比較においては無視されなければならず,識別子規則を守らな

ければならない。特性は,getterメソッド,setterメソッド又はその両方をもたなければなら

ない(8.11.3参照)。 

29) イベントを実装するメソッドは,メタデータの中にSpecialNameと印付けられなければならない

(8.11.4参照)。 

30) イベント及びそのアクセス操作子のアクセス可能性は,同一でなければならない(8.11.4参照)。 

31) イベントのためのaddメソッド及びremoveメソッドは,両方とも存在するか,両方とも存在しな

72 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

いかのいずれかでなければならない(8.11.4参照)。 

32) イベントのためのaddメソッド及びremoveメソッドは,それぞれ,その型がイベントの型を定義

する一つの仮引数をもたなければならず,System.Delegateから派生していなければならない

(8.11.4参照)。 

33) イベントは,固有の名前付けパターンを守らなければならない(10.4参照)。CLS規則29で参照さ

れたSpecialName属性は,適切な名前比較においては無視されなければならず,識別子規則を守

らなければならない(8.11.4参照)。 

34) CLSは,カスタム属性の符号化の部分集合だけを許す。これらの符号化で出現しなければならない

ものは,System.Type,System.String,System.Char,System.Boolean,System.Byte,

System.Int16,System.Int32,System.Int64,System.Single,System.Double及び

CLS合致の基底整数型に基づく列挙型だけとする(9.7参照)。 

35) CLSは,公開の可視である必す(須)修飾子(modreq,第2章参照)を許さないが,CLSが理解

しない任意選択修飾子(modopt,第2章参照)は許す(9.7参照)。 

36) 大域的に静的なフィールド及びメソッドは,CLS合致ではない(9.8参照)。 

37) 特性及びメソッドだけを多重定義できる(10.2参照)。 

38) 特性及びメソッドは,その仮引数の個数及び型にだけ基づいて多重定義できる。ただし,

op̲Implicit及びop̲Explicitという名前の変換演算子は,それらの返却型に基づいて多重定

義できる(10.2参照)。 

39) op̲Implicit又はop̲Explicitのいずれかが提供されている場合,その強制型変換に対する代

替手法を提供しなければならない(10.3.3参照)。 

40) 送出されるオブジェクトは,System.Exception又はそれを継承した型でなければならない。し

かし,CLS合致のメソッドは,他の例外型が伝ぱ(播)しないようにすることを要求しない(10.5

参照)。 

41) 属性はSystem.Attribute又はそれを継承した型でなければならない(10.6参照)。 

42) 入れ子型は,少なくとも囲んでいる型と同じ個数の総称仮引数をもたなければならない。入れ子型

の総称仮引数は,囲んでいる型の総称仮引数の位置に対応する(10.7.1参照)。 

43) 総称型の名前は,入れ子でない型で宣言された型仮引数の個数,又は,入れ子型で新たに宣言され

た型仮引数の個数を,上で定義した規則で符号化する(10.7.2参照)。 

44) 総称型は,基底型又はインタフェースに対する任意の制約が,総称型の制約を満足させることを保

障するのに十分な制約を再宣言しなければならない(10.7.3参照)。 

45) 総称仮引数に対する制約として利用される型は,それら自身がCLS合致でなければならない(10.7.4

参照)。 

46) インスタンス化された総称型内の,入れ子型を含め,そのメンバの可視性及びアクセス可能性は,

その総称型宣言全体ではなく,特定のインスタンス化された総称型の有効範囲にあるとみなさなけ

ればならない。そのようにみなすことによって,CLSの可視性及びアクセス可能性の規則12を適

用する(10.7.5参照)。 

47) 個々の抽象総称メソッド又は仮想総称メソッドには,既定の具体的な非抽象の実装が存在しなけれ

ばならない(10.7.6参照)。 

48) 一つの型の中で宣言された二つ以上のCLS合致のメソッドが同じ名前をもち,かつ,ある特定の型

のインスタンス化集合に対して,同じ仮引数及び返却値型をもつ場合,これらすべてのメソッドは,

73 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

それらの型のインスタンス化において意味的に同じでなければならない。 

12 仮想実行システム 

仮想実行システム(VES)は管理下コードを実行するための環境を提供する。これは,組込みデータ型

の集合を直接提供し,関連付けられた計算機モデル及び状態,制御フローの構築要素の集合並びに例外処

理モデルをもった仮想計算機を定義する。VESの目的は,CIL命令集合を実行するための要件を提供する

ことである(第3章参照)。 

12.1 提供されるデータ型 

CLIは,表6 CLIで直接提供されるデータ型で示されるデータ型を直接提供する。すなわち,これら

のデータ型は,CLI命令集合を使って操作することができる(第3章参照)。 

表6−CLIで直接提供されるデータ型 

データ型 

定義 

int8 

8ビットの2の補数符号付き値。 

unsigned int8 

8ビットの符号なし2進値。 

int16 

16ビットの2の補数符号付き値。 

unsigned int16 

16ビットの符号なし2進値。 

int32 

32ビットの2の補数符号付き値。 

unsigned int32 

32ビットの符号なし2進値。 

int64 

64ビットの2の補数符号付き値。 

unsigned int64 

64ビットの符号なし2進値。 

float32 

32ビットIEC 60559:1989浮動小数点数。 

float64 

64ビットIEC 60559:1989浮動小数点数。 

native int 

プラットフォーム固有の大きさの2の補数符号付き値。 

native unsigned int 

プラットフォーム固有の大きさの符号なし2進値,管理外ポインタ。 

プラットフォーム固有の大きさの浮動小数点数(VES内部用,使用者に対して
非可視)。 

管理下メモリへのプラットフォーム固有の大きさのオブジェクト参照。 

プラットフォーム固有の大きさの管理下ポインタ(管理下メモリ内を指すこと
が可能)。 

CLIモデルは,評価スタックを使用する。メモリから評価スタックに値を複写する命令は“loads”と

する。スタックからメモリに値を複写し戻す命令は“stores”とする。表6 CLIで直接提供されるデー

タ型にあるデータ型の完全な集合は,メモリ内で表現できる。しかし,評価スタック上に格納される値,

すなわち,int32,int64,native intに対する操作において,CLIはこれらの部分集合だけを取り扱

う。さらに,CLIは,内部評価スタック上の浮動小数値を表現するための内部データ型を取り扱う。内部

データ型のサイズは,実装依存とする。評価スタック上の浮動少数値の取扱いに関する更なる情報につい

ては,12.1.3及び第3章を参照。短数値(int8,int16,unsigned int8,及びunsigned int16)

は,ロードされるときに拡大化され,格納されるときに縮小化される。これは,数値及びオブジェクト参

照に関して,メモリセルが1,2,4及び8バイトであるが,スタック上に位置するときは,4又は8バイ

トの幅をもっていると仮定した計算機モデルを反映している。利用者定義の値型は,メモリ位置又は大き

さの制限をもたないスタック上に現れることができる。それらの組込みの演算は,それらのアドレスの計

算及びスタックとメモリとの間での複写だけとする。 

(4又は8バイトの整数値を単に取り扱うのではなく)短数値を特別に取り扱うCLI命令は,次の命令

だけとする。 

74 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

− メモリからのロード命令及びメモリへの格納命令: ldelem,ldind,stelem,stind 

− データ変換: conv,conv.ovf 

− 配列の生成: newarr 

符号付き整数型(int8,int16,int32,int64及びnative int)並びにそれぞれの符号なし整数

型(unsigned int8,unsigned int16,unsigned int32,unsigned int64及びnative unsigned 

int)の違いは,整数のビットをどのように解釈するかだけとする。符号なし整数が符号付き整数と異な

る扱いをする演算(例えば,比較演算又はオーバフローを生じる演算)では,整数を符号なしとして扱う

命令(例えば,cgt.un及びadd.ovf.un)が個別にある。 

この命令集合設計は,CLIからプラットフォーム固有のコードへのコンパイラ(例えばJIT)及びCIL

のインタプリタを,それらがより少ない個数のデータ型を内部的に追跡できるようにすることによって,

単純化する(12.3.2.1参照)。 

次に示すように,CIL命令は,その演算対象の型を規定しない。代わりに,CILは演算対象の型の経過

を保持する。これは,データの流れに基づき,次に示すスタックの一貫性要件に支えられて行われる。例

えば,単一のadd命令は,スタックにある二つの整数又は二つの浮動小数点数を加算する。 

12.1.1 プラットフォーム固有の大きさ:native int,native unsigned int,O及び& 

プラットフォーム固有の大きさの型(native int,native unsigned int,O及び&)は,値の大

きさの選択を遅らせるためのCLI内の機構とする。これらのデータ型はCLI型として存在するが,CLIは,

特定のCPUに対する固有の大きさにそれぞれを対応付ける(例えば,データ型IはPentium処理系ではint32

に対応付けるが,IA64処理系ではint64に対応付けられるであろう。)。したがって,CLIが初期化され,

そのアーキテクチャが知られている場合,大きさの選択はJITコンパイル時又は実行時まで遅らされる。

これは,フィールド及びスタックフレームオフセットが,コンパイル時に知られていないことを意味する。

フィールドのオフセットが初期の段階で計算されないVisual Basicのような言語では,これは困難ではな

い。C又はC++のような言語のように,ソースコードがコンパイルされるときに大きさを知っていなけれ

ばならない場合,それらが8バイト占有する保守的な仮定が受け入れられることがある(例えば,コンパ

イル時に記憶域を配置する場合)。 

12.1.1.1 native unsigned int型としての管理外ポインタ 

注記 Cのような言語では,プラットフォーム固有のコードにすべてコンパイルするとき,ポインタ

の大きさがコンパイル時に知られていて,管理下オブジェクトがない場合,固定の大きさの符

号なし整数型(unsigned int32又はunsigned int64)をポインタとして利用できる。し

かし,コンパイル時に選択されたポインタの大きさは不利な点をもっている。コンパイル時に

ポインタが32ビットの大きさをもつと選択されれば,たとえ,64ビット計算機で実行させて

もアドレス空間は4ギガバイトに制限される。さらに,32ビットコードに渡し戻されるポイン

タは常に32ビット内に適合させるように,64ビットCLIは特別なはからいを必要とする。コ

ンパイル時にポインタを64ビットとして選択されると,そのコードは32ビット計算機で実行

できるが,どのデータ構造内のポインタもCLIで必要とされる大きさの2倍になる。 

他の言語では,データ型の大きさをコンパイル時に必要としない場合,コンパイル時から,

CLI初期化時にポインタの大きさの選択を遅らせることが望ましい。その場合,同じCLIコー

ドは,そのアプリケーションが必要とする大きなアドレス空間を扱うことができる。一方,大

きなアドレス空間を必要としないアプリケーションに対して32ビットポインタの大きさに対

する利点を得ることもできる。 

75 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

native unsigned int型は,VESでの管理外ポインタを表現するために使われる。メタデータは,

管理外ポインタに強い型付けを行う方法で表現されることを許している。しかし,これらの型はVESで利

用されるnative unsigned int型に変換される。 

12.1.1.2 管理下ポインタ型:O及び& 

Oデータ型は,CLIによって管理されるオブジェクト参照を表現する。その結果,指定された操作の個

数が大きく制限される。特に,参照は,Oデータ型が参照型を操作することを示す操作(例えば,ceq及

びldind.ref)又はメタデータの参照を許可することを示す操作(例えば,call,dsfld及びstfld)

にだけ,使う。 

&データ型(管理下ポインタ)はO型に類似しているが,オブジェクトの内部を指し示す。すなわち,

管理下ポインタはオブジェクトの内部にあるフィールド又は配列の内部の要素を指し示すことが許される。

オブジェクト又は配列の先頭を指し示すことは許されない。 

オブジェクト参照(O)及び管理下ポインタ(&)は,それらが参照するデータが移動することがあるか

ら,ごみ集めの間に変更されうる。 

注記 要約すると,オブジェクト参照すなわちO型はオブジェクトの外側すなわちオブジェクトの全

体を参照する。しかし,管理下ポインタすなわち&型はオブジェクトの内部を参照する。VES

内では,参照されるオブジェクトのフィールドの受渡しが,仮引数の型を表現するために&型

を使って表現されるから,&型は,ソース言語では "参照渡し型" と呼ばれることがある。 

より柔軟に管理下ポインタを使えるように,評価スタック,静的変数及び管理外メモリといったCLIご

み集め子の制御の下にない領域を指し示すことも許される。これは,管理外ポインタ(U)が使われるの

と同じ数多くの方法で使用することも許される。すべてのコードが正当性検証可能である場合,正当性検

証の制限は,評価スタック上の値への管理下ポインタが,それが指し示す位置の生存が長く続かないこと

を保障する。 

12.1.1.3 移植性:メモリ内のポインタの格納 

calli,cpblk,initblk,ldind.*及びstind.*を含む幾つかの命令は,スタックの先頭のアドレ

スを期待する。このアドレスがメモリ内に格納されたポインタから派生されている場合,重要な移植性の

考慮すべき事柄がある。 

1) プラットフォーム固有の大きさの整数又はポインタ位置(native int型,O型,native unsigned 

int型又は&型)にポインタを格納するコードは常に完全に移植性がある。 

2) 8バイト整数(int64型又はunsigned int64型)にポインタを格納するコードは移植性がある

ようにすることができる。しかし,このことは,それがポインタとして使用される前に,

conv.ovf.un命令がメモリ形式からポインタに変換するために使われることを要件とする。また,

このことは32ビット計算機では実行時例外を発生させることがある。 

3) メモリにポインタを格納するときに,任意の短整数を使用するコード(int8,unsigned int8,

int16,unsigned int16,int32,及びunsigned int32)には,32ビット計算機上で正しく

動作するunsigned int32又はint32を利用していたとしても,一切移植性はない。 

12.1.2 短整数データ型の処理 

CLIは,4バイト整数又は8バイト整数のいずれかをもつ評価スタックであるが,1バイト整数及び2バ

イト整数も取り込むメモリモデルを定義する。正確を期すならば,次の規則をCLIモデルの一部とする。 

− 1バイト又は2バイトの位置(実引数,局所,フィールド,静的,及びポインタ)からのロードでは,

4バイト値に拡張する。既知の型(例えば,局所変数)の位置でのロードでは,アクセスされている

76 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

型が,符号拡張(符号付きの位置)又はゼロ拡張(符号なし位置)のいずれでロードするかを決定す

る。ポインタの逆参照(ldind.*)については,命令それ自身が,その位置の型を識別する(例えば,

ldind.u1は符号なし位置を示し,ldind.i1は符号付き位置を示す。)。 

− 1バイト位置又は2バイト位置に格納すると,その大きさに合わせるために切捨てが起こり,オーバ

フローエラーの保障はない。特殊な命令(conv.ovf.*)は,格納する前にオーバフローを検査する

ために利用できる。 

− メソッド呼出しは,評価スタックからそのメソッドの実引数に値が代入される。したがって,実引数

が仮引数より大きい場合,まさに他の格納で起こるような切捨てが発生する。 

− メソッドからの返却は,値を不可視な返却変数に代入するから,返却される値の型がメソッドの返却

型より大きい場合,同様に格納の時の切捨てが発生する。この返却変数の値が評価スタック上に積ま

れるから,そこで,他のロードに時に発生する符号拡張又はゼロ拡張が発生する。拡張の後の切捨て

は,計算される値を変更なしに単に残すのとは同じではない。 

これらの規則が対象とする計算機に固有の規約で正確なモデル化を確実に行うことは,CILからプラッ

トフォーム固有の機械語命令への変換の責任とする。例えば,CLIは,短整数実引数の切捨てが呼出し位

置で発生するのか又は対象とするメソッド内で発生するのかは規定しない。 

12.1.3 浮動小数点数データ型の処理 

浮動小数点数計算は,IEC 60559:1989で規定されたように処理されなければならない。この規格は,浮

動小数点数の符号化,基本操作及び基本変換の定義,丸め制御並びに例外処理について規定する。 

この規格は,特別な値,NaN(非数),正の無限大(+infinity)及び負の無限大(‒infinity)を定義する。

これらの値は,オーバフローの状態で返却される。一般的な原則は,制限のない値をもつ演算が非数を返

す一方,制限内の値をもつ演算が適切な無限大を返すことである。詳細は,IEC 60559:1989による。 

注記 次の例は,最も一般的に直面する事例を示している。 

X rem 0 = NaN 

0 * 正の無限大 = 0 * 負の無限大 = NaN 

(X / 0) = 正の無限大,if X>0 

              NaN,if X=0 

        負の無限大,if X < 0 

NaN op X = X op NaN = NaN : すべての演算について 

(正の無限大) + (正の無限大) =  (正の無限大) 

X / (正の無限大) = 0 

X mod (負の無限大) = -X 

(正の無限大) - (正の無限大) =  NaN 

注記 この規格は非正規化浮動小数点数の振る舞いについて規定していない。また,そのような表現

を生成しなければならないとき又は生成すべきかどうかについても規定していない。この規格

も,IEC 60559:1989を順守する。さらに,この規格は生成されたNaN(非数)の正確なビット

パターンへのアクセス方法及びNaNを32ビット表現と64ビット表現との間の変換に対する振

る舞いについても規定していない。この振る舞いのすべては,意図的に実装固有として残して

いる。 

比較のために,無限大値は,有限値との比較の時には,非常に大きな値をもつ妥当な符号付きの値のよ

うに振る舞う。NaNは,比較のための順序化はされない(clt,clt.un参照)。 

77 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

IEC 60559:1989標準は,通常の状況にない場合(オーバフロー,不正な演算対象など)に例外が送出さ

れることを許可しているが,CLIはこれらの例外を生成しない。その代替手段として,CLIはNaN,正の

無限大及び負の無限大を返却値に使う。また,利用者に,結果がNaN,正の無限大及び負の無限大である

かどうかの例外を生成することを許可する命令ckfiniteを提供している。 

IEC 60559:1989が定義している丸めモードは,CLIによって“最近値への丸め”(“Round to Nearest”)に

設定されなければならない。CLIもクラスライブラリも,この設定を変更するための機構を提供していな

い。CLI規格適合処理系は,この設定に対する外部インタフェースに対する弾力性をもたせる必要はない。

すなわち,浮動小数点演算を実行する前にモードを再設定する必要はなく,初期設定の一部で設定されて

いるモードに依存させることができる。 

整数変換に対して,CLIで提供されている既定の操作は“ゼロ方向への切捨て”とする。クラスライブ

ラリは,他の三つの伝統的な操作[最も近い整数を得るround(最近値への丸め),より大でない最大の整

数を得るfloor(切捨て),より小でない最小の整数を得るceiling(切上げ)]のいずれかを利用して浮動小

数点数から整数への変換を許可するように供給される。 

浮動小数点数(静的,配列の要素及びクラスフィールド)の記憶域の場所は,固定の大きさとする。提

供される記憶域の大きさはfloat32及びfloat64とする。それ以外の場所(評価スタック上の実引数,

返却値及び局所変数)の浮動小数点数は,内部の浮動小数点数型を使って表現される。このそれぞれのイ

ンスタンスにおいて,変数又は式の名目上の型はfloat32又はfloat64のいずれかであって,その値は付加

的な範囲及び/又は精度をもった内部的な表現になり得る。内部的な浮動小数点表現の大きさは実装依存

であり,様々にできるが,その精度は,表現されている変数又は式と少なくとも同じ大きさの精度をもた

なければならない。float32又はfloat64から内部表現への暗黙の拡大変換は,その型が記憶域からロ

ードされるときに実行される。その内部表現は,通常,ハードウェアに応じた固有の大きさである。すな

わち,それは操作上の効率的な実装のために要求された大きさである。その内部表現は次のような仕組を

もっていなければならない。 

− 内部表現は,名目上の型と同じかそれより大きい精度及び範囲をもたなければならない。 

− 内部表現への変換及び内部表現からの変換は値を保持していなければならない。 

注記 このことは,float32(又はfloat64)から内部表現への暗黙の拡大変換の後の,内部表現

からfloat32(又はfloat64)への明示的な変換は,もともとのfloat32(又はfloat64)

の値と同一値にすることを意味する。 

注記 この設計は,浮動小数点数が記憶域の場所に置かれるまで,CLIがプラットフォーム依存の高

性能な表現を選択することを許可している。例えば,利用者が要求する以上の精度を提供する

ハードウェアのレジスタ上に浮動小数点数を残しておくことができる。同時に,CIL生成器は,

変換命令を利用して言語に特有な規則に沿って操作することを強制できる。 

内部表現が名目上の型以上の範囲及び/又は精度をもつ浮動小数点の値が記憶域の場所に置かれるとき,

自動的に記憶域の型への強制型変換が行われる。これは,精度の消失又は範囲外の値(非数,正の無限大

又は負の無限大)の生成をともなうことができる。しかし,変更が行われていない状態で記憶域の場所か

ら再ロードされる場合には,その値は将来の利用のために内部表現内に残ってもよい。残された値が,別

名によるアクセス及び別の実行スレッド(12.6参照)の影響を考慮し,後続のロード時にも妥当であるこ

とを保障するのはコンパイラの責任とする。その内部表現が,それに関連する型で正確に表現可能としな

けばならないとき,余分な精度をもたせ,明示的な変換(conv.r4又はconv.r8)の実行が後続すると

いう自由は許可されない。 

78 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

注記 特定の記憶域型に変換できない値を検出するために,変換命令(conv.r4又はconv.r8)を

使い,その後でckfiniteを使って無限大値の検査を行うことができる。特定の記憶域型に変

換するときにアンダフローを検出するために,ゼロとの比較がその変換の前と後とで要求され

る。 

注記 float32又はfloat64より大きな内部表現の使用は,一見無関係に見える開発者のコードの

変更によって計算誤差が生じることがある。その結果は,内部表現(例えば,レジスタ内)か

らスタック上の場所に流出した値にできる。 

12.1.4 CIL命令及び算術型 

注記 この細分箇条は参考情報であり規定ではない。 

数値を扱うCIL命令の多くは,評価スタック(12.3.2.1参照)上から演算対象を取り,これらの入力は,

VESが理解する関連型をもっている。結果として,addのような単一の演算は,任意の数値データ型の入

力をもつことができる。すべての命令が,演算対象の型のすべての組合せを取り扱うわけではない。加算

及び減算以外の2項演算は,両方の演算対象が同じ型であることを要求する。加算及び減算では,管理下

ポインタ(型&及びO)に整数を加える又は減じることが許可される。詳細は,第2章による。 

数値:これらの命令は整数及び浮動小数点数の両方を扱う。整数は符号付きとして扱う。単純算術計算,

条件分岐及び比較命令がある。 

整数:これらの命令は整数だけを扱う。ビット操作及び符号なし整数の除算及び剰余算がある。 

浮動小数点数:これらの命令は浮動小数点数だけを扱う。 

特殊:これらの命令は,整数及び/又は浮動小数点数を扱うが,異なる大きさ及び符号なし整数を特別

に扱う変異形である。オーバフロー検出をともなう整数演算,データ変換命令,評価スタックとメモリの

他の場所(12.3.2参照)との間でデータを移送する操作がある。 

符号なし/順序なし:整数を符号なしとして扱い,浮動小数点数を特に順序なしと(より大きい又は順

序なしで分岐するように)みなす,特別な比較及び分岐命令がある。 

ロード定数:ロード定数(ldc.*)命令は,int32,int64,float32又はfloat64型の定数をロー

ドするのに使われる。プラットフォーム固有の大きさをもつ定数(native int型)は,conv.i又は

conv.uを使って(int64からの変換は移植性がない)int32から変換されることによって生成される。 

表7 数値種類のCIL命令には,命令の種類ごとに,数値を扱うCIL命令を示す。“.*”で終わる命令

は,(データの大きさ及びそのデータが符号付き又は符号なしで扱われるかどうかに基づいて)その命令の

すべての変異形を示す。“[.s]”は,これらの命令の長形式及び短形式の両方を意味する。 

background image

79 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

表7−数値種類のCIL命令 

add 

数値 

div 

数値 

add.ovf.* 

特殊 

div.un 

整数 

and 

整数 

ldc.* 

ロード定数 

beq[.s] 

数値 

ldelem.* 

特殊 

bge[.s] 

数値 

ldind.* 

特殊 

bge.un[.s] 

符号なし/順序なし 

mul 

数値 

bgt[.s] 

数値 

mul.ovf.* 

特殊 

bgt.un[.s] 

符号なし/順序なし 

neg 

整数 

ble[.s] 

数値 

newarr.* 

特殊 

ble.un[.s] 

符号なし/順序なし 

not 

整数 

blt[.s] 

数値 

or 

整数 

blt.un[.s] 

符号なし/順序なし 

rem 

数値 

bne.un[.s] 

符号なし/順序なし 

rem.un 

整数 

ceq 

数値 

shl 

整数 

cgt 

数値 

shr 

整数 

cgt.un 

符号なし/順序なし 

shr.un 

特殊 

ckfinite 

浮動小数点数 

stelem.* 

特殊 

clt 

数値 

stind.* 

特殊 

clt.un 

符号なし/順序なし 

sub 

数値 

conv.* 

特殊 

sub.ovf.* 

特殊 

conv.ovf.* 

特殊 

xor 

整数 

12.1.5 CIL命令及びポインタ型 

注記 この細分箇条は参考情報であり規定ではない。 

注記 オブジェクトのポインタを追跡できること及び到達可能でなくなったオブジェクトを回収する

(すなわち,ごみ集めによってメモリ管理を提供する。)ことができることを要求するCLIの

実装がある。この処理は,ワーキングセットを削減するためにオブジェクトを移動させるから,

移動したオブジェクトのポインタすべてが変更される。これを適切に動作させるために,オブ

ジェクトへのポインタはある方法でだけ利用できる。O(オブジェクト参照)及び&(管理下ポ

インタ)データ型が,これらの制約に対する形式とする。 

オブジェクト参照の使用は,CILで堅く制限されている。これは,ほぼ例外なく“仮想オブジェクト命

令”で使われる。これは,オブジェクトを扱うために特殊に設計された命令である。さらに,オブジェク

ト参照を扱うCILの基本命令がわずかにある。特に,オブジェクト参照は,次のことができる。 

1) 受け渡されるメソッドの実引数が,評価スタック上へロードされる(ldloc,ldarg)。そのスタッ

クからそのホーム場所へ格納される(stloc,starg)。 

2) 評価スタックを複製化する又は評価スタックから取り出す(dup,pop)。 

3) データ型が異ならない他のオブジェクト参照との等価性を検査する(beq,beq.s,bne,bne.s,

ceq)。 

4) 管理外コードの型についてだけ,管理外メモリからロード及び管理外メモリへの格納を行う

(ldind.ref,stind.ref)。 

5) null参照の生成(ldnull)。 

6) 値を返却する(ret)。 

80 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

管理下ポインタは,更に,次の基本操作をもつ。 

1) 管理下ポインタを返却する,バイト単位での整数の加算及び減算(add,add.ovf.u,sub,

sub.ovf.u)。 

2) 同じ配列の要素の間のバイト数を返却する,それぞれの要素を指す二つの管理下ポインタの減算

(sub,sub.ovf.u)。 

3) 二つの管理下ポインタに基づいた符号なしの比較及び条件分岐(bge.un,bge.un.s,bgt.un,

bgt.un.s,ble.un,ble.un.s,blt.un,blt.un.s,cgt.un,clt.un)。 

管理下ポインタに関する算術演算は,同じ配列の要素に対するポインタに対した使用することだけを意

図された演算とする。管理下ポインタに対する他の算術演算の動作は規定しない。 

注記 メモリ管理主体はプログラムとは非同期に実行され,管理下ポインタを変更するから,個々の

オブジェクトの間隔及びそれらの相対位置を変更できる。 

12.1.6 集約データ 

注記 この細分箇条は参考情報であり規定ではない。 

CLIは集約データを扱う。これは,部分部品(配列,構造体又はオブジェクトインスタンス)をデータ

項目にもつが,値を複写することで渡される。この部分部品に管理下メモリへの参照を含めることができ

る。集約データは値型を使って表現され,二つの方法でインスタンス化することができる。 

− ボックス化:オブジェクトとして,実行時に完全な型情報をもち,通常CILメモリ管理主体によって

ヒープ上に割り当てられる。 

− ボックス化解除:“値型インスタンス”として,実行時に型情報をもたず,ヒープ上には直接割り当て

られない。ヒープ上の大きな構造体の一部,すなわちクラスフィールド,ボックス化された値型のフ

ィールド又は配列の要素にすることができる。また,局所変数又は入力実引数の配列(12.3.2参照)

に置くこともできる。さらに,クラスの静的変数若しくは静的メンバ,又は他の値型の静的メンバと

して割り当てることもできる。 

値型のインスタンスが,メソッド実引数として規定され,メソッド呼出しで複写されるから,(クラスの

ボックス化されたインスタンス)オブジェクトという意味での同一性をもたない。 

12.1.6.1 値に対するホーム 

注記 この細分箇条は参考情報であり規定ではない。 

データ値のホームは,それを再利用できるように格納された場所とする。CLIは,次のホーム場所を直

接取り扱う。 

− 入力実引数 

− メソッドの局所変数 

− オブジェクト型又は値型のインスタンスフィールド 

− クラス,インタフェース又はモジュールの静的フィールド 

− 配列の要素 

個々のホーム場所について,ホーム場所のアドレスを(実行時に)計算する方法及びホーム場所の型を

(JITコンパイル時に)計算する方法がある。これらは表8 ホーム場所のアドレス及び型として整理する。 

background image

81 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

表8−ホーム場所のアドレス及び型 

ホームの型 

実行時のアドレス計算 

JIT時の型決定 

実引数 

値渡し実引数用のldarga又は参照渡し実引数用のldarg。 メソッド識別情報。 

局所変数 

値渡し局所用のldloca,又は,参照渡し局所用のldloc。 メソッドヘッダ内の局所識別情報。 

フィールド 

ldflda。 

クラス,インタフェース又はモジュー
ル内のフィールド型。 

静的 

ldsflda。 

クラス,インタフェース又はモジュー
ル内のフィールド型。 

配列の要素 

1次元で添字が0から始まる配列用のldelema又はインス
タンスメソッド呼出しアドレス。 

配列の要素型。 

ホームに加え,組込み値が二つの方法(すなわち,ホーム抜き。)で存在できる。 

1) 定数値(通常ldc.*命令を使ってCIL命令列に組み込まれる。)。 

2) メソッド又はCIL命令による返却時の評価スタック上の中間値。 

12.1.6.2 値型インスタンスに対する操作 

注記 この細分箇条は参考情報であり規定ではない。 

値型インスタンスは,その生成,実引数としての受渡し,値としての返却並びに局所,フィールド及び

配列要素への格納及びそれらからの抽出(すなわち,複写)を行うことができる。クラスのように,値型

は静的メンバ及び非静的メンバ(メソッド及びフィールド)の両方をもつことができる。しかし,実行時

に型情報をもち込まないから,値型インスタンスはsystem.Object型の項目に対して置換可能ではない。

この点において,組込み型int32,int64などのように振る舞う。値型インスタンスとObjectインス

タンスとの間の変換を行う二つの操作がある。これらは,ボックス化及びボックス化解除である。 

12.1.6.2.1 値型インスタンスの初期化 

注記 この細分箇条は参考情報であり規定ではない。 

値型インスタンスの初期化に対する選択肢が三つある。ホームのアドレスのロード(表8 ホーム場所

のアドレス及び型参照)及びinitobj命令(局所変数に対して,メソッドヘッダでのゼロ初期化ビット

を設定することによってもなされる。)の使用によって,それを0にできる。ホームのアドレスをロード(表

8 ホーム場所のアドレス及び型参照)し,次に構築子を直接呼び出すことによって,利用者定義の構築

子を呼び出すこともできる。また,ホーム内にある既存のインスタンスを,12.1.6.2.2で規定するように複

写できる。 

12.1.6.2.2 値型インスタンスのロード及び格納 

この細分箇条は,すべて参考とする。 

評価スタック上に値型をロードする方法が二つある。 

− ldarg,ldloc,ldfld又はldsfld命令を使って,適切な型をもつホームから値を直接ロードする。 

− 値型のアドレスを計算し,次にldobj命令を使う。 

同様に,評価スタックから値型を格納する方法が二つある。 

− starg,stloc,stfld又はstsfld命令を使って,適切な型のホームに値を直接格納する。 

− 値型のアドレスを計算し,次にstobj命令を使う。 

12.1.6.2.3 値型の引数渡し及び返却 

注記 この細分箇条は参考情報であり規定ではない。 

値型は,他の値を扱うのと全く同じように扱われる。 

82 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

− 値型を値渡しするために,単純に他の任意の実引数と同じようにldloc,ldargなどを使ってスタッ

ク上にロードする又は値型を返却するメソッドを呼び出す。値渡しされた値型仮引数にアクセスする

ために,そのアドレスを計算するldarga命令,又は,評価スタック上に値をロードするldarg命

令を使う。 

− 値型を参照渡しするために,通常行うように値型のアドレスをロードする(表8 ホーム場所のアド

レス及び型参照)。参照渡しされた値型仮引数にアクセスするためには,値型のアドレスをロードする

ldarg命令を使い,次に評価スタック上に値型をロードするldobj命令を使う。 

− 値型を返却するために,単に空の評価スタック上に値をロードし,次にret命令を実行する。 

12.1.6.2.4 メソッド呼出し 

注記 この細分箇条は参考情報であり規定ではない。 

値型に対する静的メソッドは,通常のクラスに対する静的メソッドと違いなく扱われる。すなわち,そ

のメソッドのクラスとして,その値型を指定しているメタデータトークンでcall命令を使う。非静的メ

ソッド(すなわち,インスタンス及び仮想メソッド)は,値型を扱う。しかし,特殊な取扱いが与えられ

る。(値型ではなく)参照型の非静的メソッドは,その参照型のインスタンスであるthisポインタを期待

する。参照型のインスタンスは識別性をもち,thisポインタがその識別性を表現するから,これは参照

型に対して意味がある。しかし,値型はボックス化されるときにだけ識別性をもつ。この点を扱うために,

値型の非静的メソッド上のthisポインタは,通常の値渡し仮引数ではなく,値型の参照渡し仮引数とする。 

値型の非静的メソッドは,次の方法で呼び出されてよい。 

− 値型のボックス化解除されたインスタンスが与えられると,コンパイラはオブジェクトの厳密な型を

静的に把握する。call命令は,第1仮引数(thisポインタ)として,そのインスタンスのアドレス

を受け渡す関数を呼び出すために使われる。call命令で使われるメタデータトークンは,そのメソ

ッドのクラスとして値型自身を指定しなければならない。 

− 値型のボックス化されたインスタンスが与えられると,次の三つの場合が考慮される。 

− インスタンス又は仮想メソッドが値型自身に導入される。インスタンスのボックス化解除を行い,

そのメソッドのクラスとして値型を使って,直接,そのメソッド呼出しを行う。 

− 上位クラスから継承した仮想メソッド。callvirt命令を使い,必要に応じてSystem.Object,

System.ValueType又はSystem.Enumクラスのメソッドを指定する。 

− 値型で実装されるインタフェース上の仮想メソッド。callvirt命令を使い,そのインタフェース

型のメソッドを指定する。 

12.1.6.2.5 ボックス化及びボックス化解除 

注記 この細分箇条は参考情報であり規定ではない。 

ボックス化及びボックス化解除は,概念的に値型インスタンスとSystem.Objectとの間で(高水準言

語でも見られる)キャストすることと同等とする。しかし,これはデータ表現を変更するから,ボックス

化及びボックス化解除は,参照型のキャスト(isinst及びcastclass命令)ではなく,様々な大きさ

の整数の拡大及び縮小(conv及びconv.ovf命令)に似ている。ボックス化命令は,インスタンスを複

写し,新しく割り当てたオブジェクトにそれを埋め込むことによって,値型インスタンスを

System.Objectに変換する(常に型安全な)拡大操作である。ボックス化解除は,(厳密な型が値型で

ある)System.Objectを値型インスタンスに変換する(実行時例外が発生する可能性がある)縮小操作

である。これは,インスタンスを複写せずに,埋め込まれた値型インスタンスのアドレスを計算すること

によってなされる。 

83 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

12.1.6.2.6 値型に対するcastclass及びisinst 

注記 この細分箇条は参考情報であり規定ではない。 

値型インスタンスへ及び値型インスタンスからキャストすることは許可されていない(同等な操作はボ

ックス化及びボックス化解除である。)。しかし,ボックス化のとき,System.Object型の値が特定のク

ラスのボックス化表現であるかどうかを知るために,isinst命令を使うことができる。 

12.1.6.3 非透過クラス 

注記 この細分箇条は参考情報であり規定ではない。 

アドレス算術操作及び間接参照操作によって直接操作される内容である複数バイトのデータ構造を提供

する言語がある。この機能を提供するには,CLIは,データメンバに関する情報をもたずに,指定された

大きさをもつ値型の生成を許可する。これらの非透過クラスのインスタンスは,他の任意のクラスのイン

スタンスと正確に同じ方法で扱われるが,ldfld,stfld,ldflda,ldsfld及びstsfld命令は,そ

れらの内容にアクセスするために利用してはならない。 

12.2 モジュール情報 

CLI PEファイル形式の詳細は,第2章で与える。CLIはPEファイル内で定義された個々のメソッドに

ついての次の情報に依存する。 

− すべての例外ハンドラを含む,メソッド本体を構成している命令 

− メソッド識別情報。これは,返却値型,並びに,それぞれの実引数及び実引数の個数,順序,仮引数

渡しの規約及び実引数の個々の組込み型を指定する。また,プラットフォーム固有の呼出し規約(単

にプラットフォーム固有のコードにだけ影響を与え,CIL仮想呼出し規約には影響を与えない。)も指

定する。 

− 例外処理配列。この配列は,例外がフィルタ処理され,捕そく(捉)される範囲を線引きする情報を

もつ(第2章及び12.4.2参照)。 

− メソッドが要求する評価スタックの大きさ。 

− メソッドが要求する局所配列の大きさ。 

− CLIによって局所変数及び予備メモリ領域が初期化されることが望ましいかどうかを示す

localsinitフラグ(localloc参照)。 

− 局所変数配列の識別情報の形式における局所変数の型(“局所識別情報”という。)。 

さらに,ファイル形式は,そのファイルの移植性の度合いを示すことができる。記述できる一種類の制

約がある。 

− 整数に対する特殊な32 bit長の制約。 

コード実行上に制限があることを示すことによって,CLIクラスローダは,支援できないアーキテクチ

ャ上での移植性のないコードの実行を防ぐことができる。 

12.3 計算機状態 

CLIの設計目標の一つは,CILコード生成器からメソッド呼出しフレームの詳細を隠ぺいすることであ

る。これは,CLI(CILコード生成器ではない)が,最も効率的な呼出し規約及びスタック配置を選択する

ことを許可している。この抽象化を達成するために,呼出しフレームはCLI内に統合される。次の計算機

状態の定義は,これらの設計選択を反映している。ここで,計算機状態とは,主に,大域的状態及びメソ

ッド状態からなる。 

12.3.1 大域的状態 

CLIは,多重同時実行スレッドの制御(ホストオペレーティングシステムで提供されるスレッドと同じ

background image

84 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

である必要はない。),多重管理下ヒープ及び共有メモリアドレス空間を管理する。 

注記 スレッドの制御は,多少単純化すると,メソッド状態の単一のリンクリストとしてみなすこと

ができる。ここで,メソッド呼出し命令によって,新しい状態が生成され,現在の状態にリン

クされる ‒ スタックに基づく呼出し手順の従来のモデルである。このスレッド制御のモデルは

tail.,jmp又はthrow命令の操作を正しく定義しないことに注意する。 

図2 計算機状態モデルに,計算機状態モデルを例示する。これには,スレッド制御,メソッド状態及

び共有アドレス空間内の多重ヒープを含んでいる。別の図として図3 メソッド状態で示すメソッド状態

は,スタックフレームの抽象化である。実引数及び局所変数はメソッド状態の一部であるが,任意の管理

下ヒープに格納されたデータを参照するObject参照を含むことができる。一般に,実引数及び局所変数

は,実行しているスレッドに対してだけ可視である。その一方,インスタンスフィールド及び静的フィー

ルド,並びに配列の要素は多重スレッドに対して可視にでき,その値の変更は副作用とみなされる。 

図2−計算機状態モデル 

background image

85 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

図3−メソッド状態 

12.3.2 メソッド状態 

メソッド状態は,実行しているメソッド内の環境(従来のコンパイラ用語では,“呼出しスタックフレー

ム”と呼ばれる情報のスーパーセットに対応する。)を記述する。CLIメソッド状態は,次の項目で構成さ

れる。 

− 命令ポインタ(IP)。これは,CLIによって実行される,現在のメソッド内の次のCIL命令を指す。 

− 評価スタック。このスタックは,メソッドに入るまで空とする。その内容は,そのメソッドに対して

完全に局所的であり,呼出し命令の間,維持される(すなわち,そのメソッドが別のメソッドを呼び

出した場合,その別のメソッドが返却された後,その評価スタックの内容は,まだ存在する。)。評価

スタックは,アドレス指定できない。いつでも,削減された型の集合のどれが,CIL命令ストリーム

内の特定の位置で,任意のスタックの場所に格納されるかを導出することができる(12.3.2.1参照)。 

− (添字が0から始まる)局所変数配列(添字が0から始まる。)。局所変数の値は,(評価スタックに対

するのと同じ意味で)メソッド呼出しの間,維持される。局所変数は任意のデータ型を保持できる。

しかし,特定のスロットは,型に対する一貫した方法(型システムは12.3.2.1に規定される。)で使わ

れなければならない。局所変数は,メソッドに対するlocalsinitフラグ(12.2参照)が設定されて

いる場合,メソッドに入る前に0で初期化される。個々の局所変数のアドレスは,ldloca命令を使

って取得できる。 

− 実引数配列。現在のメソッドの入力実引数の値(添字0から始まる)。これらは,論理的な添字によっ

て読込み及び書出しができる。実引数のアドレスは,ldarga命令を使って取得できる。実引数のア

ドレスは,可変長実引数並びを型安全に繰返し処理と組み合わせて使われるarglist命令によって

も暗黙的に取得される。 

− メソッド情報ハンドル。これは,メソッドに関する読込み専用の情報を含む。特に,メソッドの呼出

し識別情報,その局所変数の型及びその例外処理に関するデータを保持する。 

− 局所予備メモリ領域。CLIは局所予備メモリ領域(localloc)からオブジェクトを動的に割り当て

る命令を含む。局所予備メモリ領域内に割り当てられたメモリはアドレス指定可能とする。局所予備

メモリ領域に割り当てられたメモリは,メソッドの文脈が終了すると回収される。 

− 返却状態ハンドル。このハンドルは,現在のメソッドからの返却におけるメソッド状態を再格納する

ために使われる。一般的に,これはそのメソッドの呼出し元の状態である。これは,従来のコンパイ

ラ用語での動的リンクに対応する。 

− セキュリティ記述子。この記述子は管理下コードに対して直接アクセスできないが,セキュリティの

上書きを記録するために,CLIセキュリティシステムによって使われる(assert,permit-only及

86 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

びdeny)。 

メソッド状態の四つの領域である入力実引数配列,局所変数配列,局所予備メモリ領域及び評価スタッ

クは,論理的に異なった領域であるかのように規定される。CLI規格適合処理系は,基本となる対象とす

るアーキテクチャ上の従来のスタックフレームとして保持する又は他の同等な表現記述を利用することで,

これらの領域をメモリの一つの隣接した配列に対応づけることもできる。 

12.3.2.1 評価スタック 

個々のメソッド状態に関連する評価スタックが存在する。CLI命令の多くは,評価スタックから実引数

を取り出し,その評価スタック上に返却値を置く。他のメソッドの実引数及びその返却値も,その評価ス

タック上に置かれる。手続呼出しがなされると,その呼び出されるメソッドに対する実引数が,そのメソ

ッドの入力実引数配列(12.3.2.2参照)となる。これは,メモリの複写,又は,単に二つのメソッドによ

る二つの領域の共有を要件にできる。 

評価スタックは,値型のボックス化解除されたインスタンスを含む任意のデータを保持できるようにス

ロットで構成される。プログラムのある任意の時点でのスタックの型状態(スタックの深さ及びスタック

上の各要素の型)は,すべての可能性のある制御フローのパスに対して同一でなければならない。例えば,

未知の回数分の繰返しがあり,個々の繰返しの時にスタック上に新しい要素を積むプログラムは禁止され

る。 

一般的に,CLIは12.1で規定された型の完全集合を扱う一方,CLIは特別な方法で評価スタックを扱う。

スタック上の型を詳細に追跡するJITコンパイラがある一方,CLIは次の一つの値を要求するだけとする。 

− int64,8バイト符号付き整数。 

− int32,4バイト符号付き整数。 

− native int,対象とするアーキテクチャに,より都合がよい4バイト又は8バイトのいずれかの符

号付き整数。 

− F,浮動小数点数値(float32,float64又は基礎となるハードウェアで提供されている別の表現。)。 

− &,管理下ポインタ。 

− O,オブジェクト参照。 

− *,“一時ポインタ”。これは,単一のメソッドの本体内でだけ使われ,管理外メモリ内であることが

分かっている値を指す(詳細は,CIL命令集合仕様を参照。*型はCLI内で内部的に生成され,利用者

によって生成されない。)。 

− 利用者定義の値型。 

他の型は,次の技術を組み合わせて合成される。 

− 他のメモリ位置にある短整数型は,評価スタック上にロードされるとき,ゼロ拡張又は符号拡張され

る。これらの値は,そのホーム場所に格納され戻されるときに丸められる。 

− 異なる大きさの間及び符号付き,符号なしの間で,オーバフローの検出を伴い又は伴わずに,数値変

換を実行する特別な命令がある。 

− スタック上の整数を符号なしであるかのように扱う特殊な命令がある。 

− メモリ管理主体のヒープ(例えば,ldloca,ldarga及びldsflda)内を指さないことを保障した

ポインタを生成する命令は,管理下ポインタ(&型)又は管理外ポインタ(native unsigned int

型)が期待されている場所ならば,どこでも使用できる一時ポインタ(*型)を生成する。 

− メソッドが呼び出されるとき,管理外ポインタ(native unsigned int又は*型)は管理下ポイン

タ(&型)が要求される仮引数に対応させることが許されている。しかし,メモリ管理主体が管理下

87 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

ポインタを失わせてもよく,その逆は許されていない。 

− 管理下ポインタ(&型)は,管理外ポインタ(native unsigned int)が正当性検証可能でなく,

実行時例外を生成することがあるにもかかわらず,それに明示的に変換できる。 

12.3.2.2 局所変数及び実引数 

個々のメソッド状態の一部は,局所変数を保持する配列及び実引数を保持する配列とする。評価スタッ

クと同様に,これらの配列の個々の要素は,任意の単一のデータ型又は値型のインスタンスを保持できる。

両方の配列とも0から始まる(すなわち,最初の実引数又は局所変数は0と番号付けされる。)。局所変数

のアドレスはldloca命令を使って計算され,実引数のアドレスはldarga命令を使って計算できる。 

個々のメソッドに関連するメタデータは,次を指定する。 

− メソッドに入ったとき,局所変数及び予備メモリ領域メモリが初期化されるかどうか。 

− 個々の実引数の型及び実引数配列の長さ(可変長の実引数並びについては12.3.2.3を参照)。 

− 局所変数の型及び局所変数配列の長さ。 

CLIは対象のアーキテクチャに対して適切な詰め物を挿入する。すなわち,64ビットアーキテクチャで

ある場合,すべての局所変数は64bit境界に整列でき,その他のアーキテクチャでは8ビット,16ビット,

及び32ビットの境界に整列できる。CIL生成器は,配列内での局所変数のオフセットに対するどんな仮定

もしてはならない。実際,CLIは局所変数配列内の要素を順序化し直すことができ,実装ごとにそれぞれ

異なる方法で順序化することが許されている。 

12.3.2.3 可変長の引数並び 

CLIは未知の長さ及び型の実引数並びを受け取るメソッド(“可変個引数メソッド”)を実装するのに,

クラスライブラリと組み合わせて動作する。これらの実引数へのアクセスは,そのライブラリにある

System.ArgIteratorと呼ばれる型安全反復子(第4章参照)を通して行う。 

CILは,実引数反復子を扱うのに特殊なarglistという命令を提供する。この命令は,実引数の個数

が可変個取ると宣言されたメソッド内でだけ利用できる。これは,System.ArgIteratorオブジェクト

に対する構築子によって必要とされる値を返却する。基本的に,arglistで生成された値は,メソッドに

渡された実引数並びのアドレスと,提供された実引数の個数及び型を指定する実行時のデータ構造との両

方へのアクセスを提供する。これは,クラスライブラリが,利用者に可視である反復機構を実装するため

に十分である。 

CLIの視点から,可変個引数メソッドは,他のメソッドと同じように実引数の配列をもっている。しか

し,配列の初期部分だけが固定化された型集合をもつ。また,これらだけがldarg,starg及びldarga

命令を使って直接アクセスできる。実引数反復子は,配列内での冒頭部及び残りの実体との両方へのアク

セスを許可する。 

12.3.2.4 局所予備メモリ領域 

個々のメソッド状態の一部は,局所予備メモリ領域とする。メモリは,localloc命令を使って局所予

備メモリ領域から明示的に割り当ててよい。局所予備メモリ領域内のすべてのメモリは,メソッドを抜け

ると回収され,これが局所予備メモリ領域メモリを回収する唯一の方法とする(このメソッド呼出しの間

に割り当てられた局所メモリを解放するための命令は存在しない。)。局所予備メモリ領域はコンパイル時

に大きさ又は型が未知であり,プログラマが管理下ヒープ内で割り当ててほしくないオブジェクトを割り

当てるために使われる。 

局所予備メモリ領域はメソッドの生存期間の間,縮退できないから,言語実装系では,一般的な目的で

メモリ割当てのために局所予備メモリ領域を使用できない。 

88 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

12.4 制御フロー 

CIL命令集合は,あるCIL命令から次の命令までの通常の制御の流れを代替する豊富な命令集合を提供

する。 

− メソッド内で使われる条件分岐及び無条件分岐命令。これは保護範囲境界をまたがない転送を提供す

る(12.4.2参照)。 

− 新しい実引数を計算し,既知の又は計算された目的のメソッドに,それら及び制御を転送するメソッ

ド呼出し命令(12.4.1参照)。 

− メソッド呼出しを実行する前に,そのスタックフレームを放棄すべきメソッドを示すtail呼出し前

置子(12.4.1参照)。 

− メソッドからの返却。必要に応じて値を返す。 

− 現行メソッド実引数を既知の又は計算された目的のメソッドに転送するメソッド飛越し命令(12.4.1

参照)。 

− 例外関連命令(12.4.2参照)。これらには,例外を初期化する命令,保護領域外へ制御の転送,フィル

タ処理,catch節又はfinally節を終了させる命令を含む。 

CLIは,メソッド内での制御の転送を扱う一方,次のような順守しなければならない制約事項がある。 

1) 例外処理機構を通らずに,catchハンドラ又はfinally節に入る制御の転送は一切許可されない

(12.4.2参照)。 

2) 保護区域の外への制御の転送は12.4.2で規定されている。 

3) ret命令によって返却値が取り出された後,評価スタックは空でなければならない。 

4) スタック上の個々のスロットは,メソッド本体内で与えられた任意の場所に到達することが許可さ

れている場合,その制御の流れに関係なく,その場所では同じデータ型をもたなければならない。 

5) JITコンパイラが効率的にスタック上に格納されるデータ型を追跡できるように,スタックは,無

条件での制御転送(br,br.s,ret,jmp,throw,endfilter,endfault又はendfinally)

の後の命令の時点では,通常,空でなければならない。メソッド内の先頭に近い位置で,その命令

に前方分岐してきた場合,その命令の時点でスタックは空であってはならない。 

6) メソッドの終端に単に“通り抜け”(12.4.2.8.1)する制御は許可されない。すべてのパスは,ret

命令,throw命令,jmp命令,(又はtail.が先行するcall命令,calli命令,若しくはcallvirt

命令)のいずれか一つで終了しなければならない。 

12.4.1 メソッド呼出し 

CILコード生成器で生成される命令は,CLIのそれぞれの実装ごとに異なるプラットフォーム固有な呼

出し規約を利用するために十分な情報を含んでいる。すべてのメソッド呼出しは,次のとおりメソッド状

態領域(12.3.2参照)を初期化する。 

1) 入力された実引数配列は,呼出し元によって要求された値に設定される。 

2) 局所変数配列は,Object型及びオブジェクトを保持する値型のフィールドに対して常にnullを

もつ。さらに,localsinitフラグがメソッドヘッダで設定されている場合,その局所変数配列は,

すべての整数型に対して0に,すべての浮動小数点数型に対して0.0に初期化される。値型は,CLI

によって初期化されない。正当性検証されたコードは,メソッドの入口コードの一部として初期化

子の呼出しが供給される。 

3) 評価スタックは空とする。 

12.4.1.1 呼出し元記述子 

89 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

呼出し元は,インタプリタ又はJITコンパイラが任意のプラットフォーム固有の呼出し規約を合成でき

るような付加的な情報を規定する。すべてのCIL呼出し命令(call,calli及びcallvirt)には,呼

出し元の記述を含む。この記述は,二つの形式の一つをとることができる。より単純な形式は,calli命

令で利用され,次の情報を提供する“呼出し元記述”とする。これは,単独な呼出し識別情報に対するメ

タデータトークンとして表現される。 

− 渡されている実引数の個数 

− 個々の実引数のデータ型 

− 実引数が呼出しスタック上に置かれていた順序 

− 利用されるプラットフォーム固有の呼出し規約 

より複雑な形式は,call及びcallvirt命令で利用され,呼出し命令の呼出し先に対する識別子をも

つ呼出し元記述を補強する“メソッド参照”とする。これは,methodrefメタデータトークンである。 

12.4.1.2 呼出し命令 

CILは,新しい実引数の値を呼出し先のメソッドに転送するために使われる三つの呼出し命令をもつ。

通常の状況の下では,呼び出されたメソッドは,終了し,呼び出しているメソッドに制御を返す。 

− callは,CILが結合される時点で,呼出し先アドレスが固定化されるときに使われるように設計され

ている。この場合,メソッド参照は命令内に直接置かれる。これは,C言語の静的関数の直接呼出し

に相当する。これは,静的メソッド,インスタンスメソッド又はインスタンスメソッド本体内の(静

的に既知の)スーパークラスのメソッドを呼び出すために利用できる。 

− calliは,呼出し先のアドレスが実行時に計算されるときに使われるように設計されている。メソッ

ドポインタはスタック上に渡され,この命令は呼出し元記述だけを含む。 

− callvirtは,呼び出されるメソッドを決定するために(実行時にだけ既知になる)オブジェクトの

厳密な型を利用する。この命令は,メソッド参照を含むが,特定のメソッドは呼出しが実際に起きる

まで計算されない。これは,下位クラスのインスタンスを提供することを許可し,その下位クラスに

対する適切なメソッドを呼び出すことを許可する。callvirt命令は,インスタンスメソッドとイン

タフェース上のメソッドとの両方に対して利用される。第3章のCTS仕様及びCIL命令集合仕様を

参照。 

さらに,これらの個々の命令は,tail命令前置子を直前に置いてもよい。これは,呼び出したメソッ

ドがこのメソッド呼出しで終了(及び,呼び出されたメソッドによって返却される値を返却)することを

規定する。このtail前置子は,JITコンパイラが(呼出しが,非信頼コードから信頼コードへの呼出しで

ある場合,そのフレームはセキュリティ上の理由によって完全に放棄することはできない。)呼出しを行う

前に,呼出し側のメソッド状態を放棄することを命令する。呼び出されたメソッドがret命令を実行する

とき,制御は呼び出したメソッドではなく,そのメソッドが戻る場所に戻る(通常,呼出し側の呼出し元

である。)。tail命令は,呼出し側のフレームの生存期間を短くするから,実引数として管理下ポインタ

(型&)を渡すことは安全ではないことに注意する。 

最後に,tail.が置かれた場合に対して最適化を指示する二つの命令がある。 

− その二つとは,methodrefトークン又はmethoddefトークンが後続するjmp命令であり,それぞ

れは,現在のメソッドの状態が放棄されないことが望ましいこと,その実引数は,呼出し先のメソッ

ドにそのまま損なわれずに転送されるのが望ましいこと,及びその制御は呼出し先に転送されるのが

望ましいこと,を指示する。呼び出しているメソッド識別情報は,呼出し先メソッドの識別情報に正

確に一致しなければならない。 

90 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

12.4.1.3 計算された呼出し先 

メソッド呼出し先は,CIL命令列に直接記号化される(call命令及びjmp命令)か,計算される

(callvirt命令及びcalli命令)かのいずれかにできる。callvirt命令の呼出し先アドレスは,メ

ソッドトークン及び第1実引数(thisポインタ)の値に基づいてCLIによって自動的に計算される。メ

ソッドトークンは,第1実引数のクラスの直接基底クラスの仮想メソッドを参照しなければならない。CLI

は,要望されるメソッドの実行を提供する,第1実引数のクラスのより近い基底クラスを位置付けること

によって,正しい呼出し先を計算する。 

注記 実装は,ここで暗黙的に線形検索より効率的に行わせることを前提にしてもよい。 

calli命令に関して,CILコードは呼出し先アドレスを計算すること及びそれをスタックに積むことに

責務をもつ。これは,通常,早い段階でldftn又はldvirtfn命令を使って行われる。ldftn命令は,

メソッドを指定するCIL列内にメタデータトークンを含み,その命令はそのメソッドのアドレスをスタッ

クに積む。ldvirtfn命令は,CIL列内の仮想メソッド及びスタック上のオブジェクトに対するメタデー

タトークンをとる。これは,callvirt命令に対して,上に記述したのと同じ計算を実行するが,メソッ

ドを呼び出すのではなく,スタック上にその結果である呼出し先を積む。 

calli命令は,メソッドを呼び出すために使われることが推奨されるプラットフォーム固有の呼出し規

約に関する情報を含む呼出し元記述を含む。正当なCILコードは,呼び出されているメソッドに対する呼

出し規約に一致するcalli命令内に指定される呼出し規約を規定しなければならない。 

12.4.1.4 仮想呼出し規約 

CILは,JITによってプラットフォーム固有の呼出し規約に変換される“仮想呼出し規約”を提供する。

JITは,対象とするアーキテクチャに対する最適のプラットフォーム固有の呼出し規約を決定する。これ

は,レジスタの使用,局所的変数ホーム,値呼出しでの大きなオブジェクトの複写規約(対象とする計算

機に基づいて,何が“大きい”とするかを決定することも同様。)の詳細を含めて,プラットフォーム固有

の呼出し規約は計算機ごとに異なっていることが許される。これは,プラットフォーム固有の呼出し規約

に従って渡される実引数の場所及び順序に一致させるために,JITがCIL仮想スタック上に置かれた値を

再整列化することも許す。 

CLIは,すべてのメソッドに対して単一で一律な呼出し規約を使う。この規約を,適切なプラットフォ

ーム固有の呼出し規約に変換するのは,JIT機構の責務とする。呼出し命令(call,calli若しくは

callvirt,又は,tail.が先行するいずれか)の時点でのスタックの内容は,次のとおりとする。 

1) 呼び出されているメソッドがインスタンスメソッド(クラス若しくはインタフェース)又は仮想メ

ソッドである場合,call命令の時点で,thisポインタがスタック上の最初のオブジェクトとする。

Object(ボックス化された値型を含む)に対するメソッドでは,thisポインタは型O(オブジェ

クト参照)とする。値型に対するメソッドでは,thisポインタは参照渡し仮引数として与えられ

る。すなわち,その値はインスタンスへのポインタ(管理下&若しくは管理外*のポインタ,又は

native int)とする。 

2) 残りの実引数は,左から右の順番でスタック上に置かれる(すなわち,語い(彙)順で最も左にあ

る実引数が,スタック上の最下部にある。thisポインタがあれば,その直後となる。)。12.4.1.5では,

実装することが推奨されている三つの仮引数渡し規約(値渡し,参照渡し及び型付け参照)の個々

の方法について規定する。 

12.4.1.5 仮引数渡し 

CLIは,三つの種類の仮引数渡しを提供する。すべては,メソッド識別情報の一部としてメタデータ内

91 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

で指示される。メソッドに対する各仮引数は,それ自身の仮引数渡しの規約をもっている(例えば,第1

仮引数は値による渡しにし,その他の仮引数は参照渡しにすることができる。)。仮引数は,次の方法の一

つで渡されなければならない(次の詳細定義を参照。)。 

− 値渡し。これは,オブジェクトの値が,呼出し元から呼出し先に渡される。 

− 参照渡し。これは,データのアドレスが,呼出し元から呼出し先に渡される。したがって,その仮引

数の型は管理下ポインタ又は管理外ポインタとする。 

− 型付けされた参照。これは,データ型の実行時の表現が,そのデータのアドレスと一緒に渡される。

したがって,仮引数の型は,この目的のために特別に提供された。 

これらの規約に従うのは,CIL生成器の責務とする。正当性検証は,仮引数の型が渡された値の型に一

致することを検査する。それ以外では,呼出し規約の詳細は分からない。 

12.4.1.5.1 値渡し仮引数 

組込み型(整数,浮動小数点数など)では,呼出し元が,その呼出しの前にスタック上にその値を複写

する。オブジェクトに対して,そのオブジェクト参照(型O)がスタック上に積まれる。管理下ポインタ

(型&)又は管理外ポインタ(native unsigned int型)については,そのアドレスが呼出し元から呼

出し先に渡される。値型については,12.1.6.2を参照する。 

12.4.1.5.2 参照渡し仮引数 

参照渡し仮引数は,C++の参照仮引数又はPASCALのvar仮引数と同等とする。実引数として変数,フ

ィールド又は配列の要素の値を渡すのではなく,そのアドレスを渡す。そして,対応している仮引数の任

意の代入が,対応している呼出し元の変数,フィールド又は配列の要素を実際に変更する。この作業の多

くは,高水準言語によってなされ,値を渡すためにアドレスを計算する必要性及び値の参照又は更新のた

めの間接参照の使用を利用者から隠ぺいしている。 

参照による値の受渡しは,その値がホーム(12.1.6.1参照)をもち,その値は,渡されるホームのアドレ

スであることを要求する。定数及び評価スタック上の中間値は,それらがホームをもたないから,参照渡

し仮引数として渡すことはできない。 

CLIは,参照渡し仮引数を扱う命令を提供する。 

− ホーム位置のアドレスの計算(表8 ホーム場所のアドレス及び型参照)。 

− これらのアドレスポインタを通して組込みデータ型のロード及び格納(ldind.*,stind.*,ldfld

など)。 

− 値型の複写(ldobj及びcpobj)。 

メソッド呼出しに結びついた生存期間をもつアドレス(例えば,局所変数及び実引数)が存在する。こ

れらは,その生存期間の外側から参照されてはならない。また,そのため,その生存期間を最後に超えた

位置に格納されることもない。CILはこの制約を強制されない(及び強制できない。)。CIL生成器は,こ

の制約を強制しなければならず,そうでなければ,結果としてCILは正しく動作しない。正当性検証可能

(8.8参照)であるコードでは,参照渡し仮引数は,他のメソッドに渡されるか,又は適切なstind命令

若しくはldind命令で参照されるだけでなければならない。 

12.4.1.5.3 型付けされた参照仮引数 

参照渡し仮引数及び値型は,静的型付け言語(C++,Pascalなど)を提供するのに十分である。同様に,

これらが多様性メソッドに渡される前に,値型をボックス化する実行性能上の代償を払う動的型付け言語

(Lisp,Scheme,Smalltalkなど)も提供する。残念ながら,引数として受け入れるデータ型を静的に制限

しないメソッドにボックス化解除されたデータを参照渡しすることが要求されているVisual Basicのよう

background image

92 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

な言語を提供するには十分ではない。これらの言語は,データのホームのアドレス及びそのホームの静的

型の両方を渡す一つの方法を要求する。これは,データがボックス化された場合に提供される正確な情報

であるが,ボックス化操作に要求されるヒープの割当ては要求されない。 

型付けされた参照仮引数が,この要求に対応する。型付けされた参照仮引数は,標準の参照渡し仮引数

に非常に類似しているが,静的なデータ型が,そのデータのアドレスとともに渡される。参照渡し仮引数

のように,型付けされた参照仮引数に対応する実引数は,ホームをもつ。 

注記 正当性検証及びメモリ管理主体がデータ型と対応するアドレスを知る必要があるという事実が

なければ,参照渡し仮引数は,データのアドレス及びその型の二つのフィールドをもつ標準の

値型として実装できたかもしれない。 

通常の参照渡し仮引数のように,型付けされた参照仮引数はスタック上にあるホームを参照することが

できる。そして,そのホームは呼出しスタックによって制限される生存期間をもつ。すなわち,CIL生成

器は参照渡し仮引数の生存期間を適切に検査しなければならない。そして,正当性検証は,参照仮引数に

対してなされるように,型付けされた参照仮引数の使用に関しても同じ制約を課す(12.4.1.5.2参照)。 

型付けされた参照は,新しく型付けされた参照を生成する(mkrefany命令を使って)又は既存の型付

けされた参照を複写するかのいずれかによって渡される。型付けされた実引数が与えられると,それが参

照するアドレスはrefanyval命令を使って抽出され,それが参照する型がrefanytype命令を使って抽

出される。 

12.4.1.5.4 仮引数対応 

与えられた仮引数は,その仮引数渡し規約で,すなわち,値渡し,参照渡し又は型付けされた参照,の

いずれか一つを使って渡すことができる。単一の仮引数に対して,これらの組み合わせることはできない。

その一方,一つのメソッドが,別々の仮引数に対して,別々の呼出し規約をもつことができる。 

型付けされた参照として渡される仮引数は,実行時の型検査及び(値渡しである場合の)複写を行わず

に,参照渡し又は値渡しで渡してはならない。 

参照渡し仮引数は,静的な型を附属させることによって型付けされた参照として渡すことができる。 

表9 仮引数渡し規約に,個々のデータ型に対して利用される仮引数渡し規約を示す。 

表9−仮引数渡し規約 

データ型 

引数渡しの方法 

データを送る方法 

組込み値型 
(int,floatなど) 

値 

呼び出されたメソッドに複写される。両側で型が静的に既知である。 

参照 

アドレスが呼び出されたメソッドに送られる。両側で型が静的に既知で
ある。 

型付けされた参照 

アドレスが,呼び出されたメソッドに型情報とともに送られる。 

利用者定義値型 

値 

呼び出されたメソッドは,コピーを受け取る。両側で型が静的に既知で
ある。 

参照 

アドレスが呼び出されたメソッドに送られる。両側で型が静的に既知で
ある。 

型付けされた参照 

アドレスが,呼び出されたメソッドに型情報とともに送られる。 

オブジェクト 

値 

データの参照が呼び出されたメソッドに送られる。型は静的に既知であ
り,参照からクラスが利用できる。 

参照 

参照のアドレスが呼び出されたメソッドに送られる。型は静的に既知で
あり,参照からクラスが利用できる。 

型付けされた参照 

参照のアドレスが,静的な型情報とともに呼び出されたメソッドに送ら
れる。クラス(すなわち,動的な型)は参照から利用できる。 

93 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

12.4.2 例外処理 

例外処理は,例外オブジェクト及びコードの保護ブロックでCLIによって提供される。例外が発生した

とき,その例外を表現するオブジェクトが生成される。すべての例外オブジェクトは,あるクラスのイン

スタンスとする(すなわち,それらはボックス化された値型にできるが,ポインタ,ボックス化解除され

た値型などにはできない。)。利用者は,利用者自身の例外クラスを生成することができ,通常,それらは

System.Exception(第4章参照)の下位クラスである。 

保護ブロックに対するハンドラが四種類ある。単一の保護ブロックは,それに結びついた正確に一つの

ハンドラをもたなければならない。 

− finallyハンドラ。これは,通常の制御フローによって又は処理対象でない例外によって発生するか

どうかに関係なく,このブロックが存在するときは,必ず実行されなければならない。 

− faultハンドラ。これは,例外が発生したときに実行しなければならず,通常の制御フローが完了し

たときに実行しない。 

− catchハンドラ。これは,指定されたクラス,又は,その下位クラスの任意の例外を処理する。 

− filterハンドラ。これは,例外が,それに結びついたハンドラによって処理されるべきか又は次の

保護ブロックに渡すべきかどうかを決定するために,利用者が定義したCIL命令集合を実行する。 

保護区域,結びついたハンドラの型,並びに結びついたハンドラの位置,及び(必要に応じて)利用者

が提供するフィルタコードは,個々のメソッドに関連した例外ハンドラテーブルを通して記述される。例

外ハンドラテーブルの正確な形式は,第2章に詳細を規定する。例外処理機構の詳細も第2章で規定する。 

12.4.2.1 CLIによって送出される例外 

CLI命令は,個々の命令を実行する一部として,次の例外を送出できる。個々の命令の文書は,その命

令が送出できる例外のすべてを一覧にする。次に示した,はん(汎)用のExecutionEngineException

はすべての命令によって生成されうる。 

基本命令(第3章参照) 

− System.ArithmeticException 

− System.DivideByZeroException 

− System.ExecutionEngineException 

− System.InvalidAddressException 

− System.OverflowException 

− System.SecurityException 

− System.StackOverflowException 

オブジェクトモデル命令(第3章参照) 

− System.TypeLoadException 

− System.IndexOutOfRangeException 

− System.InvalidAddressException 

− System.InvalidCastException 

− System.MissingFieldException 

− System.MissingMethodException 

− System.NullReferenceException 

− System.OutOfMemoryException 

− System.SecurityException 

94 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

− System.StackOverflowException 

System.ExecutionEngineExceptionは特殊とする。これは,任意の命令によって送出でき,CLI

内で意図しない矛盾を示す。正当性検証されたコードの排他的な実行は,CLI規格適合処理系によってこ

の例外が送出される原因になることは一切ない。しかし,正当性検証されていないコード(CILに合致し

たコードであっても)は,メモリを破壊した場合に送出される例外の原因になりうる。適合しないCIL又

は適合しないファイル形式を実行するどんな仮定も,未規定の動作の原因となりうる。CLI規格適合処理

系は,これらの状況に対するどんな規定も設ける必要はない。 

ʻMetaDataTokenNotFound.ʼのようなことに対する例外はない。CIL正当性検証(第3章参照)は,

命令を実行する前に,この矛盾を検出し,正当性検証違反とする。CILが正当性検証しなければ,この種

の矛盾ははん(汎)用的なSystem.ExecutionEngineExceptionを送出しなければならない。 

例外は,CLIによっても送出される。また,throw命令によって利用者コードからも送出される。いずれ

の例外も発生の源に関係なく,例外処理は同一とする。 

12.4.2.2 例外の下位クラス化 

CLIによって送出される例外のある種の型は,より多くの情報を利用者に提供するために下位クラス化

できる。第3章でのCIL命令の仕様は,正常でない状況になったとき,例外のどれが実行環境によって送

出されるべきかを規定する。規格適合処理系は,その記述された型のオブジェクト又はその型の下位クラ

スのオブジェクトを送出してもよい。 

注記 例えば,ckfinite命令の仕様では,System.ArithmeticException型又は

System.ArithmeticExceptionの下位クラスがCLIによって送出されることを要求してい

る。規格適合処理系は,単に,ArithmeticException型の例外を送出してもよいが,プロ

グラマに対してより多くの情報を提供するために,原因番号をもつ

NotFiniteNumberException型の例外を送出することを選択してもよい。 

12.4.2.3 解決例外 

CILは,参照,特に,インタフェース,クラス,メソッド及びフィールドを型付けることを許す。参照

が見つからなかった又は一致しなかった場合,解決エラーが発生する。解決例外は,CIL命令からの参照,

基本クラスの参照,実装されたインタフェースの参照並びに,フィールド,メソッド及び他のクラスのメ

ンバ識別情報からの参照によって生成されうる。 

最適化に関する拡張性を許すために,解決例外の検出は,早くてインストール時及び遅くて実行時に起

こればよいという自由度が与えられる。 

CIL命令を除いて,すべての参照から解決例外の検査が行われる最も遅い機会は,参照が行われている

型の初期化の一部とする(第2章参照)。このような解決例外が検出された場合,その型の静的初期化子

があった場合,それは実行してはならない。 

CIL命令内で解決例外の検査が行われる最も遅い機会は,関連するCIL命令の最初の実行の一部とする。

CIL命令での解決例外の検査の実行を,可能な限り遅延させることを選択したとき,これらの例外は,そ

れが発生したら,VESがそのCIL命令に対して投げてよい他の任意の解決例外でない例外より前に送出し

なければならない。いったん,CIL命令が解決エラーを送出する位置を通過する(例外が発生せずに完了

する又は解決例外でない例外を投げて完了する。)と,その命令に引き続く実行は,解決例外を送出しては

ならない。 

実装が,任意の参照から,その参照の種類に対する最も遅い機会より前の段階で解決例外の検出を行う

という選択しても,すべての解決例外を早期に検出することは要件ではない。 

95 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

早期に解決エラーを検出する実装は,任意の種類の参照の後で,クラス自身内,又は,型の推移的閉包

内で検出された解決例外の結果として,そのクラスのインストール,ロード又は初期化を行わないように

できる。 

例えば,次のそれぞれが許されたシナリオである。インストレーションプログラムは,インストールさ

れている項目集合内でのCIL命令の解決エラーの検査の結果として,解決例外を送出できる(すなわち,

インストレーションが失敗する。)。実装は,参照されたクラス内のCIL命令の解決エラーの検査結果とし

て,クラスのロードを失敗させることができる。実装として,CIL命令内で解決例外をもつクラスをロー

ドすること及び初期化することが許されている。 

次の例外は,解決例外とみなされる。 

− BadImageFormatException 

− EntryPointNotFoundException 

− MissingFieldException 

− MissingMemberException 

− MissingMethodException 

− NotSupportedException 

− TypeLoadException 

− TypeUnloadedException 

例えば,参照されたクラスが見つからない場合,TypeLoadExceptionが送出される。(クラスが見つ

かり)参照されたメソッドが見つからない場合,MissingMethodExceptionが送出される。矛盾なく使

われている一致したメソッドがアクセス可能で,宣言されたセキュリティポリシーに違反している場合,

SecurityExceptionが送出される。 

12.4.2.4 例外のタイミング及び選択 

CIL命令によって送出される例外のある型は,その命令が実行される前に検出してよい。これらの場合,

送出する特定の時間を正確には定義できないが,その例外は,その命令の実行に遅延することなく送出す

ることが推奨される。例外のタイミングの緩和は,実装が任意のコードを実行する前(例えば,CILから

プラットフォーム固有のコードへの変換を行う時点)に,例外を検出することを選択できるように提供さ

れる。 

エラー条件を検出する時点と,関連する例外を送出する時点の間に差がある。エラー条件は,早期に検

出できる(例えば,JITの時)。しかし,その条件は,例外を送出する(例えば,原因の命令の実行時)ま

で,その通知を遅延させてもよい。 

次の例外が,実行時より前に送出できる例外とする。 

− MissingFieldException 

− MissingMethodException 

− SecurityException 

− TypeLoadException 

さらに,クラスの初期化がいつ発生するかについては,完全には規定されない。特に,

System.TypeInitialzationExceptionが送出されるときの保障はない。 

メソッド呼出しで二つ以上の例外の条件が生じた場合,どの例外が送出されるかは規定されない。 

12.4.2.5 例外処理の概要 

例外処理の詳細は,第2章の例外処理仕様を参照。 

96 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

実行可能なコード内の個々のメソッドは,例外処理情報の配列(空のこともある。)と結びつけられる。

この配列の個々の要素は,保護ブロック,そのフィルタ及びそのハンドラ(catchハンドラ,filterハ

ンドラ,finallyハンドラ,又は,falutハンドラでなければならない。)を記述する。例外が発生する

と,CLIは,この配列から,次の条件を満たす最初の保護ブロックを検索する。 

− 現在の命令ポインタを含む保護区域 

− catchハンドラブロック 

− その例外を処理するフィルタ 

現在のメソッドに対して一致するものが見つからない場合,呼び出しているメソッドを順次,見つかる

まで検索していく。どれにも一致しなければ,CLIはスタックトレースをダンプし,プログラムを中止す

る。 

注記 デバッガは,スタックの巻戻しを行う前に,ブレイクポイントのように,この状況に対して介

在し,取り扱うことができる。したがって,デバッガを通してスタックの検査は依然として利

用できる。 

一致するものが見つかったら,CLIはスタックを,まさに位置付けられた場所まで戻され,このときに

finallyハンドラ及びfaultハンドラを呼び出している。次に,発生した例外に対応した例外処理を開

始する。スタックフレームは,この2度目のスタック渡り歩きが起きた時か又は例外ハンドラが終了した

後かのいずれかで廃棄される。いずれになるかは,その処理ブロックに結びついた例外ハンドラ配列の要

素の情報に依存する。 

注意すべき点が四つある。 

− 例外ハンドラテーブル内での例外節の順序は重要である。ハンドラが入れ子になっている場合,最も

深い入れ子になったtryブロックは,それを囲んでいるtryブロックの前に来なければならない。 

− 例外ハンドラは,局所変数及びその例外を捕そく(捉)しているルーチンの局所予備メモリ領域にア

クセスできる。しかし,例外が送出された時点での評価スタック上の中間結果は,どれも失われる。 

− 例外を規定する例外オブジェクトは,CLIによって自動的に生成され,フィルタ又はcatch節に入り

次第,それは評価スタック上に最初の項目として積まれる。 

− filterハンドラを除いて,例外の場所で実行を再開させることはできない。 

12.4.2.6 例外に対するCILの支援 

CILは,次のような特別な命令をもつ。 

− 利用者定義例外のthrow及びrethrow。 

− 保護ブロックをleaveし,例外を送出せずに,メソッド内にある適切なfinally節を実行する。こ

れは,catch節を抜けるためにも使われる。保護ブロックからの抜出しが,fault節の呼出しを引き

起こすことはないことに注意する。 

− 利用者提供のfilter節を終え(endfilter),例外を処理するかどうかを示す値を返却する。 

− finally節(endfinally)を終え,スタックの巻戻しを続ける。 

12.4.2.7 保護ブロックの構文上の入れ子 

保護区域(“tryブロック”ともいう。)は,アドレス及び長さで記述される。trystartは保護される

最初の命令のアドレスとし,trylengthは保護区域の長さとする。tryendは,保護される最後の命令の

直後のアドレスであり,trystartとtrylengthとで自明に計算される。ハンドラ領域は,アドレス及

び長さで記述される。handlerstartはハンドラの最初の命令のアドレスとし,handlerlengthは,ハ

ンドラ領域の長さとする。handlerendはハンドラの最後の命令の直後のアドレスであり,

97 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

handlerstartとhandlerlengthとで自明に計算される。 

どのメソッドも,それに関連する例外項目の集合をもつことができる。これを例外集合と呼ぶ。例外項

目は,次の構成物で構成される。 

− 省略可能: 型トークン(扱われるべき例外の型)又はfilterstart(利用者提供のフィルタコード

の最初の命令のアドレス)。 

− 必す(須): 保護ブロック。 

− 必す(須): ハンドラ区域。4種類のハンドラ区域が存在する。catchハンドラ,フィルタで選択し

たハンドラ,finallyハンドラ,及びfaultハンドラである。フィルタで選択したハンドラは,フ

ィルタの評価が真である場合に実行されるコードである。 

例外項目がfilterstartを含むならば,filterstartは,厳密にhandlerstartより前に置く。

フィルタ領域はfilterstartで指定された命令から,handlerstartで指定されるアドレスまで(そ

のアドレスは含まない。)のすべての命令を含む。語い(彙)的にフィルタ内の最後の命令は,endfilter

でなければならない。filterstartがなければ,フィルタ領域は空とする(どの区域も重なりあわない。)。 

互いの区域と重なり合うことができる単一の例外項目の二つの区域(保護ブロック,フィルタ,ハンド

ラ区域)はない。 

例外集合内の例外項目の組合せのそれぞれに,次の一つが真でなければならない。 

− それらが入れ子になっている。一つの項目の三つすべての区域は,別の項目の単一の区域内になけれ

ばならない。さらに,囲んでいる区域はフィルタであってはならないという制約がある。 

注記 フィルタ領域内から呼び出される関数は,例外処理を含んでいてもよい。 

− それらは互いに素である。二つの項目の六つすべての区域は,組合せごとに素である(アドレスが重

なり合わない。)。 

− それらは相互に保護する。保護ブロックは同じであり,他の区域は組合せごとに素である。この場合,

すべてのハンドラは,catchハンドラ又はフィルタで選択したハンドラのいずれかでなければならな

い。ハンドラ区域の優先順序は,例外ハンドラテーブル内の順序によって決定される(第2章参照)。 

ファイル形式内への例外項目の符号化(第2章参照)は,(catchハンドラでも,faultハンドラでも,

finallyハンドラでもない)フィルタで選択したハンドラだけが唯一,フィルタをもつことができること

を保障する。 

例外処理ブロックは,保護区域,フィルタ,catchハンドラ,filterハンドラ,falutハンドラ又は

finallyハンドラのいずれかとする。 

12.4.2.8 保護ブロック上での制御フロー制限 

12.4.2.8.1 通り抜け 

命令I1は次のいずれか一つが真である場合,通り抜けが可能である。 

− 命令I1が制御フロー命令でない(すなわち,制御フローが命令I1によって変化する唯一の方法は,

それが例外を送出する場合である。)。 

− 命令I1がswitch分岐又は条件分岐である。 

注記 通り抜けは,字句のないcaseである場合である。 

− 命令I1がメソッド呼出し命令である。 

注記1 この細分箇条において,命令のとおり抜け可能性は,命令の型によって純粋に決定すること

ができる。 

注記2 多くの命令は,無条件分岐命令を実行した後に通り抜けと制御することが可能である。命令

98 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

ret,jmp,leave(.s),endfinally,endfault,endfilter,throw,及びrethrow

は,そうではない。呼出し命令は通り抜けと制御できる。これは,現在のメソッド内で実行

される次の命令は,呼出し命令の字面のうえで次の命令であるからである。この命令は,呼

出しからの戻った後に実行される。 

注記3 通り抜けに関する妥当性の決定は,字面によってなされる。制御フロー分析及びデータフロ

ー分析は要求されない。 

フィルタ又はハンドラへの入りは,CLI実行システムを通して達成される。つまり,フィルタ又はハン

ドラのブロック内に通り抜けする制御は妥当でない。このことは,フィルタ及びハンドラはメソッドの開

始時点に現れたり,又は通り抜けする制御を引き起こす任意の命令の直後に現れたりすることはできな

い。. 

注記 条件分岐は,制御フロー上,複数の効果をもたらす。その一つが,制御フローを通り抜けにで

きることなので,フィルタ又はハンドラは,条件分岐の直後に現れることはできない。 

保護ブロックへの入りは,評価スタックが空であるときに,通り抜けによって達成される。 

保護ブロック,フィルタ又はハンドラからの出は,通り抜けを経由して達成することはできない。 

12.4.2.8.2 制御フロー命令 

制御フローに影響を与える命令は,それが保護ブロック,フィルタ及びハンドラでどのように利用され

ているかに基づく制約をもつ。特定の命令は,命令の型に依存する。この細分箇条は,次の条件の基づく

制約を規定する。 

− 命令のソース。すなわち,この命令の開始アドレス。 

− 命令のターゲット。すなわち,それに続いて実行されうる同じメソッド内のすべての命令のアドレス。

ただし,12.4.2.8.1で規定した通り抜けを除く。命令がターゲット規則をもつならば,ターゲットの正

確な定義は,その規則に優先する。 

命令のソース及び個々のターゲットに関し,そのアドレスを囲んだ個々の保護ブロック,フィルタ又は

ハンドラを考慮する。すべての規則が,囲んでいる保護ブロック,フィルタ又はハンドラ,命令のソース

及びすべてのターゲットに対して満足するなら,その命令は例外処理に関して妥当であるとする(明らか

に,命令は,依然として他の妥当性規則のすべてに従わなければならない。)。命令のソースがブロックの

最初である場合でさえ,その命令は,そのブロック内にあるとみなされる。 

12.4.2.8.2.1 throw(及び次の細分箇条に掲げていないすべてのCIL命令) 

ソース 

1) ソースに関する制約はない。 

ターゲット 

1) ターゲットに関する制約はない。 

12.4.2.8.2.2 rethrow: 

ソース 

1) catchハンドラ内に囲まれていなければならない。 

注記 catchハンドラは,最も内側の囲んでいる例外処理ブロックである必要はない。例えば,catch

内にあるfinally内にrethrowがあってもよい。この場合,再送出される例外は,最も内側

の囲んでいるcatchハンドラによって捕獲された例外である。 

ターゲット 

1) ターゲットに関する制約はない。 

99 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

12.4.2.8.2.3 ret: 

ソース 

1) 保護ブロック,フィルタ又はハンドラに囲まれていてはならない。 

注記1 保護ブロック,フィルタで選択したハンドラ,又はcatchハンドラから戻るために,すべて

の例外処理ブロックの外側のアドレスに制御を移すためにleave(.s)命令が必要である。そ

して,その制御が移ったアドレスにret命令が必要である。 

注記2 tail前置命令は,ret命令が後続する命令を必要とするから,保護ブロック,フィルタ又

はハンドラの内部からtail呼出しは許されていない。 

ターゲット 

1) ターゲットに関する制約はない。 

12.4.2.8.2.4 jmp: 

ソース 

1) 任意の保護ブロック,フィルタ又はハンドラ内に囲まれていてはならない。 

ターゲット 

1) ターゲットに関する制約はない。 

12.4.2.8.2.5 endfilter: 

ソース 

1) 字面上フィルタ内の最後の命令として現れなければならない。 

注記1 endfilterに到達する制御フローが存在しない場合,例えば,フィルタ内でthrowが行わ

れる場合であっても,endfilterは必要とする。 

注記2 字面上入れ子の規則では,フィルタの内部で別の例外処理エントリを入れ子にすることを禁

止している。つまり,endfilter命令を囲んでいる最も内側の例外処理ブロックは,フィ

ルタでなければならない。 

ターゲット 

1) ターゲットに関する制約はない。 

12.4.2.8.2.6 endfinally及びendfault: 

ソース 

1) 保護ブロック,フィルタ又はハンドラを囲んでいる最も内側は,finallyハンドラ又はfaultハ

ンドラでなければならない。 

注記1 endfinally及びendfaultは,同じCIL opcode の別名の関係にある。通常,CIL アセン

ブラでは,endfinallyはfinallyハンドラ内で使うこと,及びendfaultはfaultハ

ンドラ内で使うことを要求するが,発行された命令は,いずれの名前を使っても同じである。 

注記2 finallyハンドラ又はfaultハンドラは,複数のendfinally/endfaultを含むことがで

きる。finallyハンドラ又はfaultハンドラの内部で語い(彙)的に最後の命令が,

endfinally/endfaultである必要はない。事実,すべての制御フローのパスが,他の手段

で終了される場合,例えば,finallyハンドラ又はfaultハンドラが送出する場合,

finallyハンドラ又はfaultハンドラは一切要求されなくてよい。 

ターゲット 

1) ターゲットに関する制約はない。 

12.4.2.8.2.7 分岐(br,br.s,条件分岐,switch): 

100 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

ソース 

1) 分岐のソースが保護ブロック内,フィルタ内又はハンドラ内である場合,ターゲットは同一の保護

ブロック,フィルタ又はハンドラの内部に存在しなければならない。 

ターゲット 

命令br,br.s及び条件分岐命令のターゲットは,指定されたアドレスとする。switchのターゲット

は,飛び先テーブル内に指定されたアドレスのすべてとする。 

1) 分岐の任意のターゲットが保護ブロック内にある場合,その保護ブロック内の最初の命令である場

合を除いて,そのソースは同一の保護ブロック内に存在しなければならない。 

2) 分岐のターゲットがフィルタ又はハンドラの内部にある場合,そのソースは,同一のフィルタ又は

ハンドラの内部に存在しなければならない。 

注記 コードは,保護ブロックの最初の命令に分岐することはできるが,保護ブロックの途中に分岐

することはできない。 

注記 条件分岐及びswitchは,通り抜けとなる場合があるから,それらは通り抜けの規則にも従わ

なければならない。 

12.4.2.8.2.8 leave及びleave.s: 

ソース 

1) ソースがフィルタ,faultハンドラ又はfinallyハンドラの内部に存在する場合,そのターゲッ

トは同一のフィルタ,faultハンドラ又はfinallyハンドラの内部に存在しなければならない。 

注記 これは,leave(.s)命令によって,制御をフィルタ,faultハンドラ又はfinallyハンドラ

の外に移すことができないことを意味する。 

2) ソースが保護ブロック内に存在する場合,そのターゲットは同一の保護ブロック内,又は,それを

囲んでいる保護ブロック内に存在しなければならない。又は,互いに素の保護ブロックの最初の命

令でなければならない。任意の保護ブロックの内部に存在してはならない。 

3) ソースがcatchハンドラ又はフィルタで選択したハンドラ内に存在する場合,そのターゲットは,

同一のcatchハンドラ又はフィルタで選択したハンドラ内,それに関連する保護ブロック内,若し

くは,そのcatchハンドラ又はフィルタで選択したハンドラを囲んでいる保護ブロック内に存在し

なければならない。又は,互いに素の保護ブロックの最初の命令でなければならない。任意の保護

ブロック内に存在してはならない。 

注記 ソースが任意の例外処理ブロックの外側になる場合,その事実によって,そのターゲットに関

する制約は課せられないことを意味する。実際,例外処理の外側からのleaveは,分岐のよう

に動作する。この時,評価スタックを空にする副作用をともなう。 

ターゲット 

命令leave(.s) のターゲットは,命令leave(.s) で指定されたアドレスとする。 

1) ターゲットがフィルタ又はハンドラの内部に存在する場合,そのソースは同一のフィルタ又はハン

ドラの内部に存在しなければならない。 

2) ターゲットが保護ブロックの内部に存在する場合,その保護ブロックの最初の命令である場合を除

いて,そのソースは同一の保護ブロックの内部,又は関連するcatchハンドラ若しくはフィルタで

選択したハンドラの内部に存在しなければならない。 

注記 明確に定義すると,ターゲットが保護ブロックの最初の命令である場合,そのソースはその保

護ブロックの外側に存在しえない。 

101 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

注記 これは,catchハンドラ又はフィルタで選択したハンドラから,関連する保護ブロックへ制御

を移すことができることを意味する。 

12.4.2.8.2.9 例 

例1 次のコードを例として示す。 

EX1: 

 br TryStart2 

 .try 

TryStart1: 

  

.try 

  

TryStart2: 

  

leave End 

  

  

finally 

  

  

endfinally 

  

 } 

 finally 

 { 

  

endfinally 

 } 

End: 

 ret 

EX1でのbr TryStart2命令を考える。これは,どの例外処理ブロックの内部にも含まれて

いないから,ソースに対する規則は適用されず,したがって,ソースに対する規則を満足する。

そのターゲットは,二つの保護区域の内部に含まれているから,ターゲットに対する規則が,そ

れぞれの保護区域に対して1回ずつ適用される。 

最も外側の保護区域では,そのターゲットは最も外側の保護区域の最初の命令なので,分岐の

ターゲット規則1を満足する。分岐のターゲット規則2は適用されず,したがって,分岐のター

ゲット規則2を満足する。 

最も内側の保護区域では,そのターゲットは,最も内側の保護区域の最初の命令なので,分岐

のターゲット規則1を満足する。分岐のターゲット規則2は保護区域に対して適用されず,した

がって,分岐のターゲット規則2を満足する。 

例2 次のコードを例として示す。 

 ldc.i4.0 

102 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

EX2: 

 brtrue TryStart2 

 .try 

 { 

TryStart1: 

EX3: 

  

br TryStart2 

  

.try 

  

TryStart2: 

  

leave End 

  

  

finally 

  

  

endfinally 

  

 } 

 finally 

 { 

  

endfinally 

 } 

End: 

 ret 

EX2でのbrtrue TryStart2 命令を考える。これは,どの例外処理ブロックの内部にも含ま

れないから,ソース規則は適用されず,したがって,ソース規則を満足する。そのターゲットは,

二つの保護区域の内部に含まれるから,ターゲット規則が,それぞれの保護区域に対して1回ず

つ適用される。 

そのターゲットは,内側の保護ブロックの最初の命令なので,分岐のターゲット規則1は,内

側の保護ブロックに対して満足する。しかし,そのソースが外側の保護ブロックの内部に存在せ

ず,そのターゲットがそのブロックの最初の命令でもないから,分岐のターゲット規則1は,外

側の保護ブロックに対して満足しない。 

したがって,EX2での条件分岐命令は,例外処理の視点で妥当ではない。 

次に,EX3 でのbr TryStart2 命令を考える。これは,一つの保護ブロックの内部に存在す

るから,ソース規則が,その保護ブロックに対して適用される。そのターゲットが,その保護ブ

ロックの内部に存在するから,分岐のソース規則1を満足する。そのターゲットは,二つの保護

区域の内部に含まれるから,ターゲット規則が,それぞれの保護区域に対して1回ずつ適用され

る。 

外側の保護ブロックでは,ソースは外側の保護ブロックにも存在するから,分岐ターゲット規

則1を満足する。分岐のターゲット規則2は保護ブロックに適用されず,したがって,分岐のタ

103 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

ーゲット規則2を満足する。 

内側の保護ブロックでは,そのターゲットが内側の保護ブロックの最初の命令なので,分岐の

ターゲット規則1を満足する。分岐のターゲット規則2は保護ブロックには適用されず,したが

って,分岐のターゲット規則2を満足する。 

したがって,EX3での分岐命令は,例外処理の視点で妥当である。 

例3 次のコードを例として示す。 

 .try 

 { 

  

newobj instance void [mscorlib]System.Exception::.ctor() 

  

throw 

AfterThrow: 

  

leave End 

 } 

 catch [mscorlib]System.Exception 

 { 

  

.try 

  

  

newobj instance void 

[mscorlib]System.Exception::.ctor() 

  

throw 

  

  

catch [mscorlib]System.Exception 

  

EX4: 

  

leave AfterThrow 

  

  

leave End 

 } 

End: 

 ret 

EX4 での leave 命令を考える。これは,二つのcatchハンドラの内部に含まれるから,ソ

ース規則が,それぞれの領域に対して1回ずつ適用される。 

外側のcatchハンドラでは,leave のソース規則1及びソース規則2はcatchハンドラに適

用されず,したがって,それらの規則を満足する。そのターゲットが関連する保護区域の内部に

存在するから,leave のソース規則3を満足する。 

内側のcatchハンドラでは,leave のソース規則1及びソース規則2はcatchハンドラに適

用されず,したがって,それらの規則を満足する。そのターゲットは,互いに素の保護区域の途

中に存在するから,leaveのソース規則3を満足しない。 

104 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

したがって,EX4でのleave命令は,例外処理の視点では妥当でない。しかし,説明の都合

上,そのターゲット規則についても考える。 

そのターゲットは一つの保護区域の内部に存在するから,それを保護区域とみなした場合,タ

ーゲット規則が,その保護区域に対して適用される。leaveのターゲット規則1は保護区域に提

供されず,したがって,leaveのターゲット規則1を満足する。そのソースが,保護区域に関連

するcatchブロック内に存在するから,leaveのターゲット規則2を満足する。 

例4 次のコードを例として示す。 

 .try 

 { 

  

.try 

  

  

newobj instance void 

[mscorlib]System.Exception::.ctor() 

  

throw 

  

  

catch [mscorlib] System.Exception 

  

EX5: 

  

leave EndOfOuterTry 

  

EndOfOuterTry: 

  

// … 

  

leave End 

 } 

 catch [mscorlib]System.Exception 

 { 

  

leave End 

 } 

End: 

 ret 

EX5でleave命令を考える。これは,保護区域の内部及びcatchハンドラの内部に含まれる

から,ソース規則が,それぞれに対して一度ずつ適用される。 

保護区域では,leaveのソース規則1及びソース規則3が,その保護区域に対して適用されず,

したがって,それらを満足する。そのターゲットが同一の保護区域の内部に存在するから,leave

のソース規則2を満足する。 

catchハンドラでは,leaveのソース規則1及びソース規則2は適用されず,したがって,そ

れらを満足する。そのターゲットは,catchハンドラを囲む保護区域の内部に存在するから,

leaveのソース規則3を満足する。 

105 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

そのターゲットは,一つの保護区域の内部に存在するから,それを保護区域とみなした場合,

ターゲット規則が,その保護区域に適用される。ターゲット規則1は,その保護区域には適用さ

れず,したがって,ターゲット規則1を満足する。そのソースが同一の保護ブロックの内部に存

在するから,ターゲット規則2を満足する。 

したがって,EX5でのleave命令は,例外処理の視点で妥当である。 

12.5 代理及び遠隔処理 

次のような場合,遠隔処理境界が存在する。すなわち,その境界をまたがって,オブジェクトの識別を

共有することができない場合である。例えば,二つのオブジェクトが共通のアドレス空間を共有できない

物理的に別々な計算機上に存在する場合,遠隔処理境界が,それらの計算機の間に存在する。これとは別

に,遠隔処理境界を生成する管理機構がある。 

VESは,アプリケーションドメインと呼ばれる,同一オペレーティングシステムプロセス内で実行して

いるアプリケーションをそれぞれ分離する機能を提供する。一つのアプリケーションドメイン内にロード

される型は,別のアプリケーションドメイン内にロードされる同じ型とは区別され,オブジェクトのイン

スタンスはあるアプリケーションドメインから別のアプリケーションドメインに直接共有されてはならな

い。したがって,アプリケーションドメイン自身は遠隔処理境界を形成する。 

VESは代理の概念に基づいた遠隔処理境界を実装する。代理は,境界の一方に存在し,他方のオブジェ

クトを表現するオブジェクトとする。代理は,解釈の目的のために,インスタンスフィールド及びメソッ

ドの参照を実際のオブジェクトへ移す。 

代理の実装は,System.MarshalByRefObjectから派生した型のインスタンスを自動的に提供される

(第4章参照)。 

12.6 メモリモデル及び最適化 

12.6.1 メモリ格納 

“メモリ格納”とは,CLIが操作する通常の処理メモリを意味する。概念的には,この格納は単純なバ

イト配列とする。この配列内の添字は,データオブジェクトのアドレスとする。CLIはldind.*及び

stind.*命令を通じてメモリ格納内のデータオブジェクトにアクセスする。 

12.6.2 境界調整 

組込みデータ型は,次に定義されているように,適切に境界調整されなければならない。 

− 1バイト,2バイト及び4バイトデータは,それらが,それぞれ1バイト境界,2バイト境界及び4バ

イト境界の位置に格納されたときが適切に境界調整されたとする。 

− 8バイトデータは,基礎とするハードウェアが,それにnative intに対する原子的アクセスに要求

するのと同じ境界に格納されたとき,適切に境界調整されたとする。 

すなわち,int16及びunsigned int16は偶数アドレスから開始する。int32,unsigned int32

及びfloat32は4で整除することができるアドレスから開始する。int64,unsigned int64及び

float64は,対象とするアーキテクチャに応じて,4又は8で整除することができるアドレスから開始す

る。プラットフォーム固有の大きさの型(native int,native unsigned int及び&)は,常に自然

に境界調整される(アーキテクチャに応じて,4バイト又は8バイト)。外部で生成されたとき,可搬性の

あるコードがアーキテクチャ独立であることを保障するために,これらは8バイト境界を使ってもよいが,

それらの自然なサイズに境界調整されることが推奨される。native intの大きさが32bitであっても,

float64は8バイト境界に境界調整されることを強く推奨する。 

特別な前置命令unaligned.  がある。これは,ldind,stind,initblk又はcpblk命令の直前に

106 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

先行してよい。この前置命令は,そのデータが任意に境界調整してもよいことを示し,JITには実際の境

界調整に関係なく,その命令を効果的に正しく実行するコードを生成することを要求する。さもなければ,

そのデータが適切に境界調整されず,unaligned.前置命令が指定されなければ,命令の実行は境界調整

されないメモリ障害又は不正なデータを生成できる。 

12.6.3 バイト順序 

2バイト以上のデータ型に対して,バイト順序は対象のCPUに依存する。バイト順序に依存するコード

は,すべてのプラットフォーム上で動作しなくてもよい。PEファイル形式(12.2参照)は,そのファイル

が,特定の型のバイト順序に依存していることを示す印付けを許可する。 

12.6.4 最適化 

CLI規格適合処理系は,単一のスレッドの実行において,そのスレッドによって生成される副作用及び

例外がCILによって規定された順番で可視であることを保障する任意の技術を使ってプログラムを実行す

ることを許可している。このために,揮発性操作(揮発性読込みを含む)は可視の副作用をもたらす(揮

発性操作は可視の副作用をもたらすだけとするが,それは非揮発性参照の可視性にも影響をもたらすこと

に注意する。)。揮発性操作は12.6.7で規定する。あるスレッドに他のスレッドによって注入される例外に

対して保障される順序はない(このような例外は“非同期例外”と呼ばれ, 

System.Threading.ThreadAbortExceptionがある。)。 

注記 最適化コンパイラは,プログラムの見た目の振る舞いが変わらない範囲で,副作用及び同期例

外を再順序化することができる。この点を考慮し,上記のような規定となった。 

注記 CLIの実装は,最適化コンパイラを使うことが許されている。例えば,CILを,副作用及び同

期例外の順序を(個々の単一スレッドの実行内において)同じに維持したプラットフォーム固

有の計算機コードに変換するコンパイラを提供できる。 

これは,ISO C++(評価順序点の組合せの間で再順序化が許されている。)又はISO Scheme(関数の実引

数の再順序化が許可されている。)以上の強力な条件である。 

最適化コンパイラは,メソッド内の緩和された例外に付加的な自由度を与える。メソッドは,種別Eの

例外に関して最も内側のカスタム属性 

 System.Runtime.CompilerService.CompilerRelaxationsAttributeが存在し,種別Eの例外

を緩和すると指定した場合,例外に対してE-緩和とする。ここで,“最も内側”というのは,メソッド,

そのクラス及びそのアセンブリを,この順番で検査することを意味する。 

E-緩和列は,スレッドで実行される命令列とする。ここで, 

− 可視な副作用又は例外を引き起こしている個々の命令は,E-緩和メソッド内に存在する。 

− この列は,重要な保護領域又はハンドラ領域の境界をまたぐことはない。非緩和メソッドに対する規

則に従って最適化された結果,存在しなくなりうる領域は,重要な領域ではない。 

E-検査は,失敗によって種別Eの例外の送出を引き起こすCIL命令によって実行される検査として定義

される。さらに,配列要素の値を設定又は取得するメソッド,若しくは,配列要素のアドレスを取得する

メソッドによって実行される型及び範囲の検査は,ここでの検査とみなされる。 

CLI規格適合処理系は,緩和されたE-検査が失敗するような場合にだけ,プログラムの見た目の動作を

変更する場合に限り,他の検査及び命令列に関して,E-緩和列内の緩和されたE-検査のタイミングの変更

を自由に行える。E-検査が,E-緩和列内で失敗した場合,次の規定に従う。 

− 関連する残りの命令は,正当性検証可能性を失わないために,抑制されなければならない。その命令

が VES スタック上に値を積むことを期待された命令である場合,それに後続する命令で,その値を

107 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

利用する命令はどれも実行してはならない。 

− E-緩和列内のどの副作用もVESによって明白にされるかどうかは未規定とする。 

− E-緩和列内で他の例外を送出しない限り,検査例外がそのE-緩和列内でいつか送出される。複数の緩

和された検査に失敗したとき,どの例外がVESによって送出されるかは未規定とする。 

注記 緩和された検査は正当性検証可能性を保全するが,必ずしも安全性を保証するわけではない。

緩和された検査例外を保留にし,後続のコードが実行するかもしれないから,プログラマは安

全性の確保を暗黙の検査に依存しないのが望ましい。その代わり,明示的な検査を利用し,安

全性に問題がある場合には例外を送出するのが望ましい。 

注記 プログラマには,それぞれ別々の目標がある。精密な例外の動作を放棄することは許容できな

いプログラマもいれば,最適化こそが重要というプログラマもいる。プログラマは,自分自身

の意向を指定しなければならない。どの例外が時間的に正確であるべきかという意向はプログ

ラマごとに異なるから,例外の種類ごとに緩和しても,しなくてもよい。 

注記 緩和された例外処理の背景及び実装に関する情報,並びにその例は第6章附属書Fを参照。 

12.6.5 ロック及びスレッド 

スレッド制御の論理的な抽象化は,クラスライブラリ内のSystem.Threading.Threadオブジェクト

のインスタンスによって取り込まれる。System.Threadingで始まるクラス(第4章参照)は,この抽

象化に対して,利用者に可視な多くの支援を提供する。 

スレッド実行をまたがった一貫性を生成するために,CLIは次の機構を提供する。 

1) 同期化されたメソッド:スレッド横断的に可視であるロックは,同期化されたメソッドの本体への

入りを制御する。インスタンスメソッド及び仮想メソッドでは,ロックはthisポインタに結びつ

く。静的メソッドでは,ロックは,そのメソッドが所属する型に結びつく。そのロックは,論理的

なスレッド(第4章のSystem.Threading,Threadを参照)によって取得され,同じスレッド

に何度でも入ってよい。最初のスレッドがそのロックを保持している間,他のスレッドによる入り

は禁止される。最初にロックを獲得したメソッド呼出しを抜け出すときに,CLIは,(何が何でも)

ロックを解放しなければならない。 

2) 明示的なロック及びモニタ:これらは,クラスライブラリSystem.Threading.Monitorで提供

される。このクラスのメソッドの多くは,実引数としてObjectを受け付け,同期化されたメソッ

ドによって使われる同じロックに直接アクセスが許される。CLIは,ロックが同期化されたメソッ

ドによってだけ使われるとき,正しいプロトコルを保障する責任がある。利用者は,同じオブジェ

クトに対して明示的なモニタを使うとき,この責任を受け入れなければならない。 

3) 揮発性読込み及び揮発性書出し:このCILは,volatile.前置命令を含む。これは,続く操作が

12.6.7で記述したスレッド間の可視性の制約をもって実行されることを規定する。さらに,クラス

ライブラリは明示的な揮発性読込み(System.Thread.VolatileRead)及び揮発性書出し

(System.Thread.VolatileWrite)を実行するメソッドを提供するとともに,障壁同期

(System.Thread.MemoryBarrier)を提供する。 

4) 組込みの原子的読込み及び原子的書出し:適切に境界調整されたデータ型の読込み及び書出しのす

べては,原子的に行われることが保障される(12.6.6参照)。 

5) 明示的な原子的操作:クラスライブラリは,System.Threading.Interlockedクラス内の原子

的な操作の何種類かを提供する。これらの操作(例えば,増加,減少,交換及び比較交換)は,暗

黙の獲得/解放操作で実行される。 

108 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

ロックの獲得(System.Threading.Monitor.Enter,又は,同期化されたメソッドに入ること)は,

揮発性読込み操作を暗黙に実行しなければならず,ロックの解放(System.Threading.Monitor.Exit,

又は,同期化されたメソッドから抜け出すこと)は,揮発性書出し操作を暗黙に実行しなければならない

(12.6.7参照)。 

12.6.6 原子的読込み及び原子的書出し 

CLI適合は,ある位置に対するすべての書出しアクセスが同じ大きさのとき,プラットフォーム固有の

ワードの大きさ(native intの大きさ)より長くない適正に境界調整されたメモリ位置への読込み及び

書出しアクセスは原子的であることを保障しなければならない(12.6.2参照)。原子的書出しは,書き出さ

れるビット以外を変更してはならない。明示的な配置制御(第2章 インスタンスの配置制御 参照)が

既定の動作を変更するために使われなければ,自然のワードの大きさ(native intの大きさ。)より長

いデータ要素は,適切に境界調整されなければならない。オブジェクト参照は,それがプラットフォーム

固有のワードの大きさに格納されているかのように扱われなければならない。 

注記 クラスライブラリとして原子的な更新を提供した一部のメソッドを除いて,メモリの原子的な

更新(読込み─更新─書出し)を保障しない(第4章参照)。“小さなデータ項目”(プラットフ

ォーム固有のワードの大きさより長くない項目。)の原子的書出しは,小さなデータ項目の直接

書出しを提供しないハードウェア上で,原子的な読込み─更新─書出しを行うことを要求する。 

注記 native intが32ビットのとき,ある実装が8バイトデータを8バイト境界に境界調整する

とき,原子的なアクセスの実行ができるとしても,その8バイトデータに原子的なアクセスを

する保障はない。 

12.6.7 揮発性読込み及び揮発性書出し 

ある命令に対するvolatile.前置命令は,スレッド間のメモリ順序規則を保障しなければならない。

これらには,12.6.6の規定によって保障される以外に,原子性を提供しない。 

揮発性読込みは,“獲得の意味規則”をもつ。これは,読込みが,CIL命令列内でのその読込み命令の後

で起こるメモリの任意の参照より前に起こることが保障されることを意味する。揮発性書込みは,“解放の

意味規則”をもつ。これは,書出しが,CIL命令列内のその書出し命令より前の任意のメモリ参照より後

に起こることが保障されること意味する。 

CLI規格適合処理系は,揮発性操作のこの意味規則を保障しなければならない。これは,すべてのスレ

ッドで,他の任意のスレッドによって実行される揮発性書出しの実行順序を守ることを保障する。しかし,

CLI規格適合処理系は,すべてのスレッドの実行から見た揮発性書出しの単一の総合的な順序を提供する

ことを要求しない。 

CILをプラットフォーム固有のコードに変換する最適化コンパイラは,どの揮発性操作も削除してはな

らず,単一の操作に複数の揮発性操作を融合させてはならない。 

注記 揮発性操作の従来の一つの使用方法は,直接メモリアクセスを通して可視であるハードウェア

レジスタをモデル化することである。この場合,その操作の削除又は融合は,プログラムの振

る舞いを変更してしまう。これらの点を考慮して,上記のような規則となった。 

注記 CILからプラットフォーム固有のコードへ変換する最適化コンパイラは,コードを再順序化す

ることができ,12.6で規定された単一スレッドの意味規則と,揮発性操作のスレッド間の意味

規則との両方の保障を提供する。 

12.6.8 それ以外のメモリモデルの問題 

静的変数(PEファイル内でRVAに割り当てられたものを除く。第2章参照)及びオブジェクトに割り

109 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

当てられるすべてのメモリは,それらが使用者コードで可視になる前にゼロに設定されなければならない。 

CLI規格適合処理系は,マルチスレッド環境で適切な利用者による同期化がなくても,オブジェクトを,

非認証メモリアクセス及び不当な操作を発生させない方法で割り当てることを保障しなければならない。

特に,マルチプロセッサメモリシステム上では,明示的な同期化は,すべての関連するデータ構造(例え

ば,vtableポインタ)が可視であることを保障することが要求される。VESは,この自動的な同期化の強

制又は非fatal,非不正,利用者可視の例外内の同期化の欠如によるエラーの変換のいずれかに責任をもた

なければならない。 

構築子内で実行されるすべての状態更新が,その構築子が完了する前に一様に可視にすることをCLI規

格適合処理系に保障させることは明らかに要件ではない。CIL生成器は,メモリ障壁又は揮発性書込み命

令に適切な呼出しを挿入することによってこの要件を保障できる。 

第2章 メタデータ定義及び意味 

序論 

第2章は,メタデータを規定する。すなわち,メタデータの(ファイル形式としての)物理的な配置,

メタデータの(複数の表の集合及び表間の関係としての)論理的な内容及びメタデータの(仮想アセンブ

ラとしてのilasmから見た)意味を規定する。 

概要 

第2章は,メタデータの意味及び構造に焦点をあてる。VES(仮想実行システム)のほとんどの操作を

定めたメタデータの意味を,CILのためのアセンブリ言語ILAsmの構文を用いて記述する。ILAsm構文は,

この規格の一部として,箇条5〜21で与える。ILAsmのためのアセンブラの実装は,第6章で記述される。

論理的構造及び物理的構造は,箇条22〜25に示す。 

注記 メタデータの意味をILAsmの構文を用いて記述する根拠は,アセンブリ言語をファイル中のメ

タデータ及びそのファイル中のCIL命令を指定するための構文として扱うことによる。ILAsm

は,高水準言語を使わず,CLIのために直接書かれたプログラムを交換する手段を提供する。

また,例を示す簡便な方法も提供する。 

メタデータの意味は,格納される実際の形式と独立に記述できる。これは,箇条22〜25に従

った記憶域形式で,記憶域の容量及びアクセス時間の両方を効率化できるよう設計できるから

重要となる。しかし,これは,意味記述にとって望ましい単純性を犠牲にする。 

妥当性検証及び正当性検証 

妥当性検証は,ファイルの形式,メタデータ及びCILに自己矛盾がないことを確認するために任意のフ

ァイル上で行う試験の集合を適用することをさす。これらの試験は,ファイルがこの規格の必す(須)規

定要件に適合することを保証する。CLI規格適合処理系に非適合ファイルが与えられたときの振る舞いは,

未規定とする。 

正当性検証は,CILコード列がプログラムの論理アドレス空間の外側のメモリへのアクセスを許さない

ことを保証するためにCIL及びその関連するメタデータの両方の検査とする。妥当性検証試験と正当性検

証を組み合わせれば,アクセス許可されないメモリ又は他の資源へプログラムがアクセスできないことを

保証する。 

第3章は,CIL命令の適正,かつ,正当性検証可能な使用規則を規定する。さらに,第3章は,メタデ

background image

110 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

ータの内部整合性(その規則は,間接的ではあるが,第3章の規定から得られる。)を評価するための規

則を参考として提供する。また,正当性検証アルゴリズムの規範の記述も含む。基礎となる型システムの

健全性の数学的証明は,可能であり,正当性検証要件のための基盤をも提供する。これらの規則を除けば,

この規格は,次を未規定のままとする。 

− (あるとすれば)そのようなアルゴリズムが,実行されることが望ましい時刻。 

− 規格適合処理系が正当性検証を失敗した場合に行うことが望ましいことは,何か。 

図1は,この関係を明らかにする(詳細は,次の段落で示す。)。 

図1−適切なCIL及び正当性検証可能なCILの間の関係 

図1では外部の円は,ILAsm構文によって許されるコードをすべて含む。次の内円は,適正なCILすべ

てのコードを表す。さらに,その内円は,すべての型安全なコードを表す。最後に,黒い最内円は,正当

性検証可能なコードをすべて含む(型安全なコードと正当性検証可能なコードとの間の相違の一つは,証

明可能性とする。VES正当性検証アルゴリズムは,定義によって,正当性検証可能とする。しかし,より

深い分析ならば,真に型安全と証明できるとしても,その単純なアルゴリズムでは,拒否されるコードが

ありうる。)。プログラムが第6章に記述された構文に従っても,第2章及び第3章で示された制限を順守

しなければ,そのコードは妥当ではないことに注意する。 

正当性検証の処理は,非常に厳格とする。妥当性検証は通るが正当性検証に失敗するプログラムは,多

数ある。VESは,これらのプログラムが,アクセスが許されないメモリ又は資源へのアクセスをしないこ

とを保証することができない。それにもかかわらず,プログラム自体は,そのような資源にアクセスしな

いように正確に構築されているかもしれない。したがって,これらのプログラムを動作させることが安全

かどうかは,数学的証明の問題ではなく,信頼の問題となる。これは規格外の信頼制御管理事項になるが,

通常,CLI規格適合処理系は,正当性検証不能コード(正当性検証を通っていない正当なコード。)が実行

されることを許すことができる。通常,CLI規格適合処理系は,正当性検証可能なコードの実行を許可し

なければならない。しかし,そのようなコードは,処理系で指定された追加的な信頼制御の対象となりう

る。 

例 

注記 

この箇条は参考情報であり規定ではない。 

4.1 

例Hello World 

ILAsmの一般的な感じをつかむために,よく知られた“Hello world!”というあいさつ(挨拶)を出力す

111 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

る次の簡単な例を考察する。このコードは,標準アセンブリmscorlib(第4章参照)の一部のクラス

System.Consoleにある静的メソッドWriteLineを呼び出す。 

例 (参考): 

.assembly extern mscorlib {} 

.assembly hello {} 

.method static public void main() cil managed 

{ .entrypoint 

  .maxstack 1 

  ldstr "Hello world!" 

  call void [mscorlib]System.Console::WriteLine(class System.String) 

  ret 

.assembly extern宣言は,System.Consoleの定義を含む外部アセンブリmscorlibを参照する。

2行目の.assembly宣言は,このプログラムのためのアセンブリの名前を宣言する(アセンブリはCLI

のための実行可能な内容の配備単位とする。)。.method宣言は,大域メソッドmainを定義し,それに続

く本体は,中かっこ({})で囲まれる。本体中の最初の行は,このメソッドがこのアセンブリ用の入口点

(.entrypoint)となることを示す。また,本体中の2行目(.maxstack)は,必要とするスタックの

スロットの数は多くても一つであることを指定する。 

メソッドmainは,わずか三つの手順ldstr, call及びretだけを含む。命令ldstrは,文字列定数

“Hello world!”をスタックに入れる。そして命令callは(CILの中の文字列リテラルは,標準クラ

スSystem.Stringのインスタンスとなることに注意する。),その文字列をただ一つの実引数として

System.Console::WriteLineを呼び出す。呼出し命令は,呼び出される側のメソッドの完全な呼出し

情報を含まなければならない。最後の命令retは,mainから戻る。 

4.2 

例 

第2章は,CLIメタデータのほとんどの特徴のための総合的な例を含んでいる。多くの箇条及び細分箇

条が,何らかの機能の典型的な使用を示す例で締めくくる。これらの例は,すべてILAsmアセンブリ言語

を用いて書かれている。さらに,第6章は,ILAsmアセンブリ言語の中で書かれたプログラムのより長い

例を含んでいる。当然だが,例は,すべて規定ではない。 

一般的な構文 

箇条5は,文法の大部分に共通の,ILAsm構文について記述する。 

注記 逆斜線(U+005C)は,日本語環境上では,円記号で表示される場合がある。 

5.1 

一般的な構文記法 

第2章は,修正BNF構文記法の形式を使用する。5.1は,この記法の概要とする。 

終端記号は,等幅フォントで記述する(例 .assembly,extern,float64)。しかしながら,区切

り文字だけからなる終端記号は,一重引用符でくく(括)る(例 ʻ:ʼ,ʻ[ʼ,ʻ(ʼ)。構文の種類の名前は,

《》でくく(括)り(例 《クラス宣言》),そのクラスの実際のインスタンスに置き替えられなければな

らない。角括弧(例 [《ファイル名》],[《浮動小数点数》])に置かれた項目は,省略可能とする。また,

“*”が後続する項目(例 《16進バイト》*,[ʻ.ʼ 《識別子》] *)は,ゼロ回以上現れることができる。

文字“|”は,その項目及びその横の項目のいずれか一方が受理可能とする(例 true | false)。省略

112 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

可能な項目は,英字順(より具体的には,ASCII順で,大文字と小文字とを区別しない。)で整列させられ

る。規則が省略可能な項で始まる場合,省略可能な項は,整列では考慮されない。 

ILAsmは,大文字と小文字とを区別する言語とする。すべての終端記号は,第2章で規定されるのと同

じ文字で使用しなければならない。 

例  

《最上位》 ::= 《Int32》 | float 《Float》 | 

          floats [《Float》[, 《Float》]*] | else 《引用文字列》 

のような文法は,次のすべてを妥当とする。 

     12 

     float 3 

     float ‒4.3e7 

     floats 

     floats 2.4 

     floats 2.4, 3.7 

     else "Something ¥t weird" 

しかし次のすべてを妥当ではないとする。 

     else 3 

     3, 4 

     float 4.3, 2.4 

     float else 

     stuff 

5.2 

基本構文要素 

これらの種類は,入力における構文制約を記述して,メタデータの情報に論理的な制約を課す。 

《Int32》は,10進数又は“0x”から始まる16進数のいずれかであって,32ビットで表現されなけれ

ばならない。 

注記 ILAsmには,8ビット又は16ビット整数定数という概念はない。その代わり,16.2に見られる

int8(...)及びint16(...)のような定数が要求される状況において《Int32》を代用し,最小上位バ

イトだけを使用することを許す。 

《Int64》は,10進数又は“0x”から始まる16進数のいずれかで,64ビットで表現されなければなら

ない。 

《16進バイト》は,0〜9,a〜f及びA〜Fの文字集合から成る1対の文字とする16進数とする。 

《実数》は,他のすべての構文の種類用とは異なる浮動小数点数のための任意の構文的な表現とする。

第2章ではピリオド(.)は,整数部及び小数部を分離するために使用される。また,“e”又は“E”は,

指数と仮数とを分ける。ピリオド又は仮数区切り子のいずれか(しかし両方ではない。)が,省略できる。 

注記 完全なアセンブラは,さらに,無限大及びNaN(Not a Number:非数)のための構文を供給して

もよい。 

《引用文字列》は,二重引用符(")に囲まれた文字列とする。引用文字列内では文字“¥”を,エスケ

ープ文字として使用できる。“¥t”を,タブ文字として使用することができる。“¥n”を,復帰改行文字と

して使用できる。また,文字“¥”に続く三つの8進数字を,その値をもつバイトを表すために使用できる。

“+”演算子を,文字列リテラルを連結するために使用できる。長い文字列は短く分割し,“+”でつなぎ

background image

113 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

合わせることができる。別な使い方として,行の最後の文字として“¥”を使用する。その場合にはその文

字とそれに続く改行は,生成された文字列に入力されない。次の行の上の“¥”及び最初の非空白文字の間

のすべての空白文字(空白,改行,復帰文字及びタブ)も,無視される。 

注記 《引用文字列》における二重引用文字を包含するためには,8進エスケープ手順を使う。 

例  

次の結果としての文字列は,“Hello World from CIL!”と等価とする 

    ldstr "Hello " + "World " +  

    "from CIL!" 

及び 

    ldstr "Hello World¥ 

      ¥040from CIL!" 

注記 完全なアセンブラは,Unicode符号化を使うのに必要な問題点のすべてに対処する必要がある。

第1章8.5.1を参照(特にCLS規則4)。 

《一重引用符文字列》は,二重引用符の代わりに一重引用符(′)を用いることを除いて,《引用文字列》

と同様とする。 

注記 《一重引用文字列》における二重引用文字を包含するためには,8進エスケープ手順を使う。 

《ID》は,英字(A-Z,a-z)又は“̲”,“$”,“@”,“̀”(抑音アクセント),“?”のうちの一つで始まり,

任意の個数の英数字(A-Z,a-z,0-9)又は“̲”,“$”,“@”,“̀”(抑音アクセント)及び“?”が続く一連

の隣接した文字列とする。《ID》は,次の二通りでだけ使用される。 

− 《ID》は,CIL命令のラベルとして使用される(5.4参照)。 

− 《ID》は,《識別子》として使用される(5.3参照)。 

5.3 

識別子 

識別子は,実体に名づけるために用いられる。単純識別子は,《ID》と同等とする。しかしながら,ILAsm

構文は,Unicode文字セット(第1章参照)を用いて記述することができるあらゆる識別子の使用を認め

る。これを達成するために,識別子は,一重引用符内に置かれなければならない。これは,次の文法で要

約される。 

《識別子》 ::=  
  《ID》 
   | 《一重引用符文字列》 

キーワードは,それが一重引用符内に現れるならば,そのキーワードは識別子として使用される場合に

限る(すべてのキーワードは,第6章に示す。)。 

《識別子》は,より大きな《識別子》を記述するためにドット(.)によって組み合わせることができる。

このように記述された《識別子》は,《ドット名》と呼ばれる。 

《ドット名》 ::= 《識別子》[ʻ.ʼ《識別子》]* 

注記 根拠としては,“.”は,《一重引用符文字列》構文を用いて《識別子》に含めることができるか

ら,《ドット名》は,便宜的に提供されることによる。《ドット名》は,“.”が共通の文字と考

えられる文法(例えば完全限定型名)の中で使用される。 

例 

次は,幾つかの単純識別子を示す。 

     A 

background image

114 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

     Test  

     $Test  

     @Foo?  

     ?̲X̲ 

     MyTypè1 

次は,一重引用符中の識別子を示す。 

     ′Weird Identifier′  

     ′Odd¥102Char′ 

     ′Embedded¥nReturn′ 

次は,ドットがついた名前を示す。 

     System.Console 

     ′My Project′.′My Component′.′My Name′ 

     System.IComparablè1 

5.4 

ラベル及びラベルの並び 

ラベルは,プログラムの便宜をはかるために提供される。ラベルは,メタデータ中で符号化される数値

を表現する。ラベルによって表現される値は,典型的には現在のメソッドの始めからのバイト指定でのオ

フセットとする。ただし,正確な符号化は,論理的なメタデータ構造体中又はCILストリーム中のラベル

の場所に応じて異なる。ラベルがメタデータ中でどのように符号化されるかの詳細は,箇条22から25で

示す。CIL命令でのそれらの符号化については,第3章で示す。 

単純ラベルは,アドレスを表現する特殊な名前とする。構文的にはラベルは,《識別子》と同等とする。

したがってラベルは,一重引用符で囲まれてもよいし,Unicode文字を含むこともできる。 

ラベルの並びは,コンマで分離され,単純ラベルの任意の組合せをとりうる。 

《ラベル又はオフセット》::= 《識別子》 
《ラベル列》::= 《ラベル又はオフセット》 [ʻ,ʼ《ラベル又はオフセット》]* 

注記 実際のアセンブラでは,《ラベル又はオフセット》の構文は,記号ラベルを要求せず,直接数値

を指定することがある。 

ILAsmは,2種類のラベル,すなわち,コードラベル及びデータラベルを区別する。コードラベルは,

末尾にコロン(“:”)をつけ,実行される命令のアドレスを表現する。コードラベルは,命令の前に現れ,

ラベルの直後の命令のアドレスを表現する。コードラベル名は,メソッド中で2度以上宣言してはならな

い。 

コードラベルとは対照的にデータラベルは,一つのデータ片の格納域を指定し,コロン文字を含まない。

データラベルを,コードラベルとして使ってはならない。また,コードラベルを,データラベルとして使

ってはならない。データラベル名は,モジュール中で2度以上宣言してはならない。 

《コードラベル》 ::= 《識別子》ʻ:ʼ 
《データラベル》 ::= 《識別子》 

例  

次は,命令ldstrのアドレスを表現するコードラベルldstr̲labelを定義する。 

ldstr̲label: 

ldstr "A label" 

5.5 

16進バイトの並び 

バイト列は,一つ以上の16進バイト列からなる。 

background image

115 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

《バイト列》::= 《16進バイト》 [《16進バイト》*] 

5.6 

浮動小数点数 

浮動小数点数を指定するために二つの異なる方法がある。 

1) 《実数》として指定する方法。 

2) 括弧内に整数を伴ったキーワードfloat32又はfloat64を用いて指定する方法。その整数は,浮

動小数点数の2進数表現とする。例えば,float32(1)は4バイトで表現され,値は1.401298E-45

となり,float64(1)は8バイトで表現され,その値は,4.94065645841247E-324となる。 

《Float32》  ::= 
  《実数》 
| float32 ʻ(ʼ 《Int32》 ʻ)ʼ 
《Float64》 ::= 
 《実数》 
| float64 ʻ(ʼ 《Int64》 ʻ)ʼ 

例 

5.5 

1.1e10 

float64(128) 

//注記 :これは整数128と同じビットをもつ8バイト値になる。 

5.7 

ソース行情報 

メタデータは,変数の構文範囲,すなわち,ソース行番号とCIL命令の対応付けに関する情報をもたな

い。それにもかかわらず,この情報を別な符号化の生成で使用するために,この情報を供給するためのア

センブラ構文を規定することは,有用となる。 

.lineは,行番号,コロンが先頭についたけた数(省略可能),及び参照しているファイル名を指定す

る一重引用符文字列(省略可能)を,この順番でとる。 

《外部ソース宣言》 ::= .line 《Int32》 [ʻ:ʼ 《Int32》 ] [ 《一重引用符文字列》 ] 

5.8 

ファイル名 

文法要素には,ファイル名を必要とするものもある。ファイル名は,“.”を正常な成分文字と考えた名

前とする。ファイル名用の構文は,基礎とするオペレーティング システムの規定に従う。 

《ファイル名》::= 

箇条 

  《ドット名》 

5.3 

5.9 

属性及びメタデータ 

型及び型のメンバの属性は,型及び型のメンバの定義に記述的情報を付ける。最も共通の属性があらか

じめ定義されて,その属性に関連したメタデータに特有の符号化を行う(箇条23参照)。さらに,メタデ

ータは,幾つかの異なる符号化を用いて,メタデータに利用者定義属性を付ける方法を提供する。 

構文的には,ILAsmの中の属性を指定する方法は次とする。 

− ILAsmに組み込まれた特殊な構文を使用する方法。例えば《クラス属性》においてキーワードprivate

(非公開)は,型の可視属性が,定義しているアセンブリ内でだけアクセスを許可するように設定し

なければならないことを指定する。 

− ILAsmのはん用構文を使用する方法。非終端記号《カスタム宣言》は,この文法について記述する(箇

条21参照)。擬似カスタム属性と呼ばれる幾つかの属性については,この文法は結果としてメタデー

タ内の特殊な符号化の設定になる(21.2.1参照)。 

− セキュリティ属性は,特別に扱われる。XMLで表現したセキュリティ属性の直接記述を可能にする特

background image

116 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

殊な構文が,ILAsmにはある(箇条20参照)。22.10に記述された一つの共通機構を用いて,標準ラ

イブラリにおいて,又は,利用者に提供される拡張において定義される他のすべての属性は,メタデ

ータ中で符号化されるが,セキュリティ属性(セキュリティ属性は,直接的又は間接的に

System.Security.Permissions.SecurityAttributeから継承しているという事実によって

区別される。第4章参照)は,22.11に記述されるように符号化されなければならない。 

5.10 ilasmソースファイル 

ilasmへの入力は,最上位の宣言の列とする。定義は次のとおりとする。 

《ILファイル》  ::= 

細分箇条 

《宣言》* 

5.10 

最上位の宣言のための完全な文法を,次に示す。箇条の欄又は細分箇条の欄に記載されている箇条番号

又は細分箇条番号の該当項目には,この文法の対応する生成規則の詳細が含まれる。これらの生成規則は,

“.”から始まる名前をもつ。この名前を,指令と呼ぶ。 

《宣言》 ::= 

細分箇条 

  .assembly 《ドット名》 ʻ{ʼ 《アセンブリ宣言》* ʻ}ʼ 

6.2 

| .assembly extern 《ドット名》 ʻ{ʼ 《アセンブリ参照宣言》* ʻ}ʼ 

6.3 

| .class 《クラスヘッダ》 ʻ{ʼ 《クラスメンバ》* ʻ}ʼ 

10 

| .class extern 《移出属性》 《ドット名》 ʻ{ʼ 《外部クラス宣言》* ʻ}ʼ 

6.7 

| .corflags 《Int32》 

6.2 

| .custom 《カスタム宣言》 

21 

| .data 《データ宣言》 

16.3.1 

| .field 《フィールド宣言》 

16 

| .file [nometadata] 《ファイル名》 .hash ʻ=ʼ ʻ(ʼ 《バイト列》 ʻ)ʼ 
        [.entrypoint ]  

6.2.3 

| .method 《メソッドヘッダ》  ʻ{ʼ 《メソッド本体項目》* ʻ}ʼ 

15 

| .module [《ファイル名》] 

6.4 

| .module extern 《ファイル名》 

6.5 

| .mresource [public | private] 《ドット名》 ʻ{ʼ 《目録資源宣言》* ʻ}ʼ 6.2.2 
| .subsystem 《Int32》 

6.2 

| .vtfixup 《vtfixup宣言》 

15.5.1 

| 《外部ソース宣言》 

5.7 

| 《セキュリティ宣言》 

20 

アセンブリ,目録及びモジュール 

アセンブリ及びモジュールは,CLIにおいて,役割ごとに構築要素をまとめる。 

アセンブリは,1単位として配置された一つ以上のファイルの集まりとする。アセンブリは,次の四つ

を指定する目録を常に含む(6.1参照)。 

− アセンブリ用の版,名前,文化圏及びセキュリティ要件 

− このアセンブリに属する他のファイル(存在するなら)。それらのファイルのそれぞれの暗号ハッシュ

情報も与える。目録自身は,常にアセンブリに属すファイルのメタデータ部分に存在している。 

− アセンブリから移出される,アセンブリの他のファイルにおいて定義された型。目録と同じファイル

に定義された型は,型自体の属性に基づいて移出される。 

− 省略可能とするが,目録自体用のデジタル署名及びそれを計算するために用いる公開かぎ(鍵)。 

モジュールは,第2章で規定された書式で実行可能な内容を含む単一のファイルとする。モジュールが

background image

117 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

目録を含んでいる場合,その目録は,アセンブリを構成するモジュール(目録自体を含む。)も規定する。

アセンブリは,そのすべての構成ファイル中に一つの目録だけを含むことができる。(単に動的にロードさ

れるのではなく)実行されるアセンブリでは,目録は,入口点を含んでいるモジュール中に存在しなけれ

ばならない。 

幾つかのプログラム言語は,名前空間の概念を導入していて,CLIは,この概念をメタデータ符号化技

術において採用する。型名は,それらが定義されるアセンブリに相対的な完全名によって常に指定される。 

6.1 

モジュール,アセンブリ及びファイルの概要 

注記 この細分箇条は参考情報であり規定ではない。 

図2は,参照の様々な形式を明確にする。 

図2−モジュール及びファイルへの参照 

八つのファイルが,各々の名前を,ファイルの下に伴って示されている。各々モジュールを宣言する六

つのファイルは,それらのまわりに追加の境界線をもっており,名前はMで始まる。他の二つのファイル

は,Fで始まる名前をもっている。これらのファイルは,ビットマップのような資源ファイル又はCILコ

ードを含まない他のファイルとすることができる。 

ファイルM1及びM4は,モジュール宣言に加えてアセンブリ(すなわち,アセンブリA及びB)をそ

れぞれ宣言する。M1及びM4の中のアセンブリ宣言は,直線で示された他のモジュールを参照する。例

えば,アセンブリAは,M2及びM3を参照する。また,アセンブリBはM3及びM5を参照する。した

がって,両方のアセンブリはM3を参照する。 

通常,一つのモジュールは,一つのアセンブリにだけ属する。しかし,複数のアセンブリがモジュール

を共有することは,可能とする。アセンブリAが実行時にロードされる場合,M3のインスタンスは,ア

センブリAのためにロードされる。アセンブリBが,おそらくアセンブリAと同時に,同じアプリケー

ション領域に読み込まれる場合,M3は,両方のアセンブリに共有される。両方のアセンブリは,F2も参

照する(同様の規則を適用する。)。 

モジュールM2は,点線で示すようにF1を参照する。Aが実行される場合,結果としてF1は,アセン

ブリAの一部として読み込まれる。したがって,ファイル参照は,アセンブリ宣言にも現れなければなら

ない。同様に,Bが実行される場合,M5は,Bの一部になる別のモジュールM6を参照する。したがって,

アセンブリBは,更に,M6に対してモジュール参照をもたなければならない。 

6.2 

アセンブリの定義 

アセンブリは,メタデータに目録を含んでいるモジュールで規定される(22.2参照)。目録のための情報

は,文法の次の部分で生成される。 

background image

118 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

《宣言》 ::= 

細分箇条 

  .assembly 《ドット名》 ʻ{ʼ 《アセンブリ宣言》* ʻ}ʼ 

6.2 

| .assembly extern 《ドット名》 ʻ{ʼ 《アセンブリ参照宣言》* ʻ}ʼ 

6.3 

| .corflags 《Int32》 

6.2 

| .file [nometadata] 《ファイル名》 .hash ʻ=ʼ ʻ(ʼ 《バイト列》 ʻ)ʼ  
        [.entrypoint ] 

6.2.3 

| .module extern 《ファイル名》 

6.5 

| .mresource [public | private] 《ドット名》ʻ{ʼ 《目録資源宣言》* ʻ}ʼ 6.2.2 
| .subsystem 《Int32》 

6.2 

| … 

指令.assemblyは,目録を宣言し,どのアセンブリに現在のモジュールが属するかを指定する。モジ

ュールは,指令.assemblyを多くても一つだけを含むことができる。《ドット名》は,アセンブリの名前

を指定する。 

注記 標準ライブラリアセンブリは,第4章で記述される。 

注記 幾つかのプラットフォームは,名前の大文字と小文字とを区別しないので,大文字と小文字と

が異なるだけの名前をもつアセンブリを宣言すべきでない。 

指令.corflagsは,出力PEファイルのCLIヘッダ中のフィールドを設定する(25.3.3.1参照)。CLI規

格適合処理系は,このフィールドの値が1になっていることを期待しなければならない。後方互換性のた

めに,下位3ビットは,予約済みとする。この規格の将来の版は,8と65,535の間の値に定義を供給する

かもしれない。実験的な使用及び非標準の使用は,65,535を超える値を使用することが望ましい。 

指令.subsystemは,アセンブリが(ライブラリとして別のプログラムに使用されるのではなく。)直

接実行される場合に限り使用される。指令.subsystemは,PEファイルヘッダに指定された値を格納す

ることによって,プログラムに必要なアプリケーション環境の種類を指定する(25.2.2参照)。任意の32

ビット整数を供給できるが,CLI規格適合処理系は,次の二つの取りうる値だけを尊重する必要がある。 

− 値が2である場合,プログラムは,GUIをもっているアプリケーションに適切な取決めを適宜用いて

動作することが望ましい。 

− 値が3である場合,プログラムは,キーボード入出力の操作をともなうアプリケーションに適切な取

決めを適宜用いて動作することが望ましい。 

例  

.assembly CountDown 

{ .hash algorithm 32772 

  .ver 1:0:0:0 

.file Counter.dll .hash = (BA D9 7D 77 31 1C 85 4C 26 9C 49 E7 02 BE 

E7 52 3A CB 17 AF) 

6.2.1 

アセンブリ(《アセンブリ宣言》)に関する情報 

次の文法は,アセンブリに関して指定できる情報を示す。 

《アセンブリ宣言》 ::= 

記述 

箇条又は
細分箇条 

  .custom 《カスタム宣言》 

カスタム属性を表す。 

21 

background image

119 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

| .hash algorithm 《Int32》 

指令.fileの中で使用されたハッシュアルゴ
リズム。 

6.2.1.1 

| .culture 《引用文字列》 

このアセンブリの文化圏を表す。 

6.2.1.2 

| .publickey ʻ=ʼ ʻ(ʻ 《バイト列》 ʻ)ʼ 起案者の公開かぎ(鍵)を表す。 

6.2.1.3 

| .ver 《Int32》 ʻ:ʼ 《Int32》 ʻ:ʼ 
《Int32》 ʻ:ʼ 《Int32》 

主版,副版,ビルド及び改訂を表す。 

6.2.1.4 

| 《セキュリティ宣言》 

アクセス許可が必要か,望ましいか又は禁
止されているかを表す。 

20 

6.2.1.1 

ハッシュ アルゴリズム 

《アセンブリ宣言》 ::= .hash algorithm 《Int32》 | … 

アセンブリが複数のファイルからなる場合(6.2.3参照),そのアセンブリの目録は,自分自身以外の各々

のファイルに対して,その名前及びその内容の暗号ハッシュの両方を指定する。アルゴリズムは,指定さ

れたハッシュを計算するために用いる。そしてアルゴリズムは,アセンブリに含まれるすべてのファイル

に対して同じでなければならない。すべての値は,将来のために予約済みとする。さらに,CLI規格適合

処理系は,SHA-1(第1章 3. のFIPS-180-1参照)ハッシュ関数を使用しなければならない。また,CLI

規格適合処理系は,32772(0x8004)の値を用いて,このアルゴリズムを指定しなければならない。 

注記 根拠としては,SHA-1が標準化のときに最良の広く利用可能な技術として選ばれたことによる

(第1章参照)。すべてのCLI規格適合処理系は,実行可能なイメージの可搬性を保証するす

べてのアルゴリズムを実装することを要求するから,単一のアルゴリズムが選ばれた。 

6.2.1.2 

文化圏 

《アセンブリ宣言》 ::= .culture 《引用文字列》 | … 

存在するならば,アセンブリが特殊な文化圏用に変更されたことを示す。ここで使用する文字列は,ク

ラスSystem.Globalization.CultureInfoで受理可能なものとして第4章で規定されたものでなけ

ればならない。アセンブリ参照とアセンブリ定義との比較に使用された場合,これらの文字列は大文字と

小文字とを区別しないやり方で比較されなければならない(23.1.3参照)。 

注記 文化圏の名前は,インターネット技術標準化委員会RFC1766の名前に従う。その書式は,

“<language>-<country/region>”とする。ここで,<language>はJIS X 0412-1の中の小文字2文

字符号とし,<country/region>は,JIS X 0304の大文字2文字の符号とする。 

6.2.1.3 

起案者の公開かぎ(鍵) 

《アセンブリ宣言》 ::= .publickey ʻ=ʼ ʻ(ʼ 《バイト列》 ʻ)ʼ | … 

CLIメタデータは,アセンブリ作成者がアセンブリの暗号ハッシュを(SHA-1ハッシュ関数を用いて)

計算し,次に,RSAアルゴリズム(第1章参照)及び作成者が選択した 公開/秘密かぎ(鍵)対を用いて,

それを暗号化することを可能にする。この結果(すなわち,“-SHA-1/RSAデジタル署名”)は,RSAアル

ゴリズムによって要求されるかぎ(鍵)対の公開部とともにメタデータに格納されることを可能とする。

指令.publickeyは,署名を計算するために使用された公開かぎ(鍵)を指定するために使用される。ハッシ

ュを算出するために,署名をゼロにしてハッシュを算出し,その結果を,署名に格納する。 

標準ライブラリ(第4章参照)のアセンブリはすべて公開かぎ(鍵)00 00 00 00 00 00 00 00 04 00 00 00 00 

00 00 00を使用する。このかぎ(鍵)はこの規格において標準公開かぎ(鍵)として知られている。 

アセンブリ参照(6.3参照)は,コンパイル時にこの情報のうちの幾つかを取り込む。実行時では,アセ

ンブリ参照に含まれていた情報は,アセンブリの目録からの情報とまとめることが可能であり,それによ

って,参照が生成された時(コンパイル時)及びそれが解決される時(実行時)に生成される両方のアセ

ンブリに,同じ秘密かぎ(鍵)の使用保証を可能とする。 

background image

120 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

厳密な名前(SN)による署名処理は,このような署名処理において標準的なハッシュアルゴリズム及び

暗号アルゴリズムを使用する。PEファイルの大部分を網羅するSHA-1ハッシュが生成される。そのハッ

シュ値は,厳密な名前の秘密かぎ(鍵)でRSA署名される。検証のために,公開かぎ(鍵)は,署名され

たハッシュ値と同様にPEファイルに格納される。 

PEファイルは,次に示すものを除きすべてハッシュされる。 

− 検証コード識別情報入口:PEファイルは,検証コード署名をすることができる。検証コード識別情報

は,このディレクトリ入口によって規定される範囲のPEファイルの内容及びPEヘッダデータディレ

クトリ(25.2.3.3における“証明書表”)のオフセットが128バイト目の8バイトの入口に含まれる。 

注記 規格適合のPEファイルでは,この入口をゼロとする。 

− 厳密な名前のBLOB:CLIヘッダ(25.2.3.3における“厳密名識別情報”)におけるオフセットが32バ

イト目の8バイトの入口及びPEファイルの中のこのRVAに含まれるハッシュデータの内容。入口が

ゼロである場合,厳密名識別情報との関連はない。 

− PEヘッダチェックサム :PEヘッダWindows NT特有フィールド(25.2.3.2における“ファイルチェ

ックサム”)におけるオフセットが64バイト目の4バイトの入口 

注記 規格適合のPEファイルでは,この入口をゼロとする。 

6.2.1.4 

版番号 

《アセンブリ宣言》 ::= .ver 《Int32》 ʻ:ʼ 《Int32》 ʻ:ʼ 《Int32》 ʻ:ʼ 《Int32》 
| … 

アセンブリの版番号は,四つの32ビット整数で指定する。この版番号は,コンパイル時に取り込まれ,

コンパイルされたモジュール内のすべてのアセンブリへの参照要素として使用されなければならない。 

すべての標準アセンブリは,最後の二つの32ビット整数を0に設定しなければならない。個々の実装者

は,この規格の将来の版との競合を回避するために,最後の二つの32ビット整数を両方とも0に設定しな

いようにするように促されるが,この規格は,版番号の使用に他の要件を課さない。 

この規格の将来の版は,標準アセンブリのために指定された最初の二つの32ビット整数のうち一つ又は

両方を次の条件の場合には変更しなければならない。その条件とは,付加的な機能が加えられるか,その

実装のためにVESに何らかの追加機能が必要となった場合とする。さらに,この規格の将来の版では,最

初の二つの32ビット整数のうち一つ又は両方をmscorlibアセンブリの指定のために変更しなければならな

い。これは,その版番号が,プログラムを動作するのに必要な実行エンジンの異なる版を識別するために

(もし望まれれば)使用できるようにする。 

注記 規格適合処理系は,版番号を完全に無視できる。又は,参照付ける場合,厳密な一致を要求で

きる。又は,適切とみなされる他のどんな振る舞いも示すことができる。次に使用法を示す。 

1) 版番号の1番目の32ビット整数は,主版番号とみなす。同じ名前をもつが異なる主版のア

センブリは交換可能ではない。例えば,後方互換性を想定することが可能でない製品の大

きな書換えの場合に,主版番号を変えることが適切だろう。 

2) 版番号の2番目の32ビット整数は,副版番号とみなす。同じ名前及び主版をもつが異なる

副版のアセンブリは,著しい拡張だが後方互換性の意図を示す。副版番号を変えることは,

例えば,製品の小さな変更又は製品の新版に完全後方互換性がある場合に適切だろう。 

3) 版番号の3番目の32ビット整数は,ビルド番号とみなす。また,ビルド番号だけ異なるア

センブリは,同じソースからの再コンパイルを表現する。例えばプロセッサ,プラットフ

ォーム又はコンパイラの変更のために,ビルド番号を変えることは適切だろう。 

background image

121 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

4) 版番号の4番目の32ビット整数は,改訂番号とみなす。同じ名前,主版番号及び副版番号

をもつが,異なる改訂番号をもつアセンブリは,完全交換可能を意図する。改訂番号を変

えることは,例えば,以前に提供されたアセンブリのセキュリティホールを修復する場合

に適切だろう。 

6.2.2 

目録資源 

目録資源は,アセンブリに関連したデータの名前付き項目とする。目録資源は,指令.mresourceを用

いて導入される。指令.mresourceは,その前にある宣言.assemblyによって始まるアセンブリ目録に

目録資源を加える。 

《宣言》 ::= 

細分箇条 

.mresource [public | private] 《ドット名》ʻ{ʼ 《目録資源宣言》* ʻ}ʼ 

| … 

5.10 

目録資源がpublicと宣言された場合,目録資源は,アセンブリから移出される。目録資源は,private

と宣言された場合,移出されず,この場合,アセンブリの内部からだけ利用可能となる。《ドット名》は,

資源の名前とする。 

《目録資源宣言》 ::= 

記述 

箇条又は 
細分箇条 

  .assembly extern 《ドット名》 

目録資源は,名前が《ドット名》の外
部アセンブリとする。 

6.3 

| .custom 《カスタム宣言》 

カスタム属性 

21 

| .file 《ドット名》 at 《Int32》 

目録資源は,ファイル《ドット名》中
のバイトオフセット《Int32》にある。 

モジュールでないファイル(例えば添付テキストファイル)に格納された資源については,そのファイ

ルを,別途(最上位の).file宣言(6.2.3参照)を用いて,目録中で宣言しなければならない。また,バ

イトオフセットは,ゼロとしなければならない。同様に,別のアセンブリにおいて定義される資源は,指

令.assembly extern(6.3参照)を用いて参照され,それは,別途(最上位の)指令.assembly extern

で定義されていなければならない。 

6.2.3 

アセンブリに関係するファイル 

アセンブリは,他のファイル(例えば文書,実行の間に使用される他のファイル。)に関係付けられる。

宣言.fileは,アセンブリの目録にそのようなファイルへの参照を加えるために使用される(21.19参照)。 

《宣言》 ::= 

細分箇条 

  .file [nometadata] 《ファイル名》 .hash = ʻ(ʼ 《バイト列》 ʻ)ʼ  
[.entrypoint]  

| … 

5.10 

この規格に従えばモジュールでないファイルの場合,属性nometadataを指定する。nometadataと

して印がついているファイルは,どんな書式にもできる。それらは,純粋なデータファイルとみなす。 

.hashの後の《バイト列》は,そのファイル用に計算されたハッシュ値を指定する。VESは,このファ

イルをアクセスする前にこのハッシュ値を再計算しなければならない。そして,二つのハッシュ値が合わ

ない場合,VESの動作は未規定とする。このハッシュ値を計算するために使われるアルゴリズムは,.hash 

algorithm(6.2.1.1参照)で指定される。 

指令.entrypointが指定された場合,それは,多重モジュールアセンブリの入口点がこのファイルに

含まれることを示す。 

6.3 

アセンブリの参照 

background image

122 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

《宣言》 ::=  

細分箇条 

  .assembly extern 《ドット名》 [ as 《ドット名》 ] ʻ{ʼ 《アセンブリ参
照宣言》* ʻ}ʼ 

| … 

5.10 

アセンブリは,それが含んでいるファイルからの他のアセンブリへのすべてのアクセスを調停する。こ

れは,実行アセンブリの目録が,実行コードによって参照されるアセンブリのための宣言を含むことを要

求することによって,メタデータを通じて行われている。最上位の.assembly extern宣言は,この目

的に使用される。省略可能なas節は,ILAsmが同じ名前だが,版,文化圏などが異なる外部アセンブリを

指定するための別名を提供する。 

.assembly externで使用される《ドット名》は,大文字と小文字との区別も含めて,指令.assembly

によって宣言されるアセンブリの名前と正確に一致しなければならない(したがって,たとえ,アセンブ

リが,大文字と小文字との区別がないファイルシステム内のファイル内に格納されていても,メタデータ

の内部に格納された名前は,大文字と小文字とを区別しなければならず,正確に一致しなければならない。)。 

《アセンブリ参照宣言》 ::= 

記述 

箇条又は 
細分箇条 

  .hash ʻ=ʼ ʻ(ʼ 《バイト列》 ʻ)ʼ 

参照されたアセンブリのハッシュ 

6.2.3 

| .custom 《カスタム宣言》 

カスタム属性 

21 

| .culture 《引用文字列》 

参照されたアセンブリの文化圏 

6.2.1.2 

| .publickeytoken ʻ=ʼ ʻ(ʼ 《バイ
ト列》 ʻ)ʼ 

発行者の公開かぎ(鍵)のSHA-1ハッシュの
下位8バイト 

6.3 

| .publickey = ʻ(ʼ 《バイト列》 ʻ)ʼ 発行者の完全公開かぎ(鍵) 

6.2.1.3 

| .ver 《Int32》 ʻ:ʼ 《Int32》 ʻ:ʼ 
《Int32》 ʻ:ʼ 《Int32》 

主版,副版,ビルド,及び改訂 

6.2.1.4 

これらの宣言は,.publickeytokenが追加されている点を除いて.assembly宣言のためのものと同

じとする(6.2.1参照)。.publickeytoken宣言は,アセンブリ参照において,完全公開かぎ(鍵)の代

わりに,発行者の公開かぎ(鍵)のSHA-1ハッシュの下位8バイトを格納するために使用される。 

アセンブリ参照では,完全公開かぎ(鍵)又は8バイトの“公開かぎ(鍵)トークン”のいずれかを格

納できる。いずれも,コンパイル時にアセンブリに署名するために使用された同じ秘密かぎ(鍵)が,実

行時に使用されるアセンブリを署名したか検証するために使われる。いずれも存在しなくて構わない。ま

た,両方を格納することもできるが,これは,有用ではない。 

CLI規格適合処理系は,この妥当性検証を実行する必要はない。しかし,CLI規格適合処理系は妥当性

検証の実行を許されている。また,CLI規格適合処理系は,妥当性検証が失敗したアセンブリのロードを

拒絶できる。CLI規格適合処理系は,更に,アセンブリ参照が完全公開かぎ(鍵)又は公開かぎ(鍵)ト

ークンのいずれかを含んでいなければ,アセンブリへのアクセス許可を拒絶できる。CLI規格適合処理系

は,公開かぎ(鍵)又はトークンが使用されるかどうかとは別に,同じアクセス決定を下さなければなら

ない。 

注記 根拠としては,アセンブリ参照に格納された公開かぎ(鍵)又は公開かぎ(鍵)トークンは,

参照されたアセンブリ及び実行時に実際につかわれるアセンブリが同じ公開かぎ(鍵)を所有

する実体によって生成されたことを保証するために使われることによる。また,すなわち,公

開かぎ(鍵)又はアセンブリ参照に格納された公開かぎ(鍵)トークンは,同じ目的を意図し

ていることを仮定することができる。完全な公開かぎ(鍵)は,暗号としてより安全である一

方,その参照に,より多くの記憶域を要求する。公開かぎ(鍵)トークンの使用は,妥当性検

background image

123 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

証処理を若干弱める一方,その参照を格納するために必要な領域を削減する。 

注記 アセンブリの内容が,それが作成されて以来改ざんされていないことを検証するために,アセ

ンブリの自己識別性での完全公開かぎ(鍵)が使われ,アセンブリへの参照に格納された公開

かぎ(鍵)又は公開かぎ(鍵)トークンは使われない。 

例  

.assembly extern MyComponents 

{ .publickeytoken = (BB AA BB EE 11 22 33 00)  

  .hash = (2A 71 E9 47 F5 15 E6 07 35 E4 CB E3 B4 A1 D3 7F 7F A0 9C 24) 

  .ver 2:10:2002:0 

6.4 

モジュールの宣言 

すべてのCILファイルはモジュールとする。また,ファイル名ではなくメタデータにもちこまれた論理

名によって参照される(22.30参照)。 

《宣言》 ::= 

細分箇条 

| .module 《ファイル名》 

| … 

5.10 

例  

.module CountDown.exe 

6.5 

モジュールの参照 

項目が,現在のアセンブリ内にあるが,目録を含んでいるものとは別のモジュールの一部である場合,

定義するモジュールは,指令.module externを用いて,アセンブリの目録の中で宣言されなければな

らない。参照するアセンブリの指令.module externの中で使用される名前は,定義するモジュールの

指令.module(6.4参照)の中で使用される名前と厳密に一致しなければならない(22.31参照)。 

《宣言》 ::= 

細分箇条 

| .module extern 《ファイル名》 

| … 

5.10 

例 

.module extern Counter.dll 

6.6 

モジュール又はアセンブリの内部の宣言 

モジュール又はアセンブリの内部の宣言は,次の文法によって指定される。各項目についての詳しい情

報は,対応する箇条又は細分箇条で示す。 

《宣言》 ::= 

箇条又は 
細分箇条 

| .class 《クラスヘッダ》 ʻ{ʼ 《クラスメンバ》* ʻ}ʼ 

10 

| .custom 《カスタム宣言》 

21 

| .data 《データ宣言》 

16.3.1 

| .field 《フィールド宣言》 

16. 

| .method 《メソッドヘッダ》 ʻ{ʼ 《メソッド本体項目》* ʻ}ʼ 

15. 

| 《外部ソース宣言》 

5.7 

| 《セキュリティ宣言》 

20 

| … 

background image

124 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

6.7 

移出された型定義 

アセンブリ一つについて一つだけ存在する目録モジュールは,指令.assembly を含む。アセンブリの

他のモジュールに定義された型を移出するには,アセンブリの目録中に登録しなければならない。次の文

法が登録の形式を定義する。 

《宣言》 ::= 

箇条 

  .class extern 《移出属性》 《ドット名》 ʻ{ʼ 《外部クラス宣言》* ʻ}ʼ  
| … 

《外部クラス宣言》 ::= 

箇条 

  .file 《ドット名》 

| .class extern 《ドット名》 

| .custom 《カスタム宣言》 

21 

《移出属性》の値は,public又はnested publicでなければならない。また,型の可視性に一致し

なければならない。 

例えば,アセンブリが二つのモジュールA.EXE及びB.DLLからなると仮定する。A.EXEは目録を含ん

でいる。公開クラスFooはB.DLLにおいて定義済みとする。Fooを移出するために,すなわち,Fooを

他のアセンブリによって可視にし,他のアセンブリから使用可能にするためには,指令.class extern

が,A.EXEに含まれなければならない。反対に,A.EXEで定義された公開クラスBarは,指令.class 

externを必要としない。 

注記 根拠としては,ツールは,アセンブリによって定義された型の全集合を決定する単一のモジュ

ール(目録モジュール)を取り出すことが望まれることによる。したがって,アセンブリ内の

他のモジュールからの情報も,目録モジュールの中で複写される。慣例によって,目録モジュ

ールはアセンブリとしても知られている。 

型及び識別情報 

メタデータは,型の定義及び参照の両方の機構を供給する。箇条10は,インタフェース型,クラス型及

び値型に共通した,型定義のメタデータについて記述する。型参照に使用される機構は,二つの部分から

なる。 

− 参照されるが(典型的には)現在のモジュールにおいて定義済みでない利用者定義型の論理的な記述。

生成された記述は,メタデータ中の表に格納される(22.38参照)。 

− 様々な修飾子とともに一つ以上の型参照を符号化する識別情報。文法上での非終端記号《型》は,識

別情報の個別要素を記述する。識別情報の符号化は,23.1.16で規定する。 

7.1 

型 

次の文法は,CLIシステムの(ポインタ型を含む)すべての組込み型を規定する。さらに,CLIシステ

ムにおいて定義できる利用者定義型のための構文も示す。 

《型》 ::= 

記述 

箇条又は 
細分箇条 

ʻ!ʼ《Int32》 

0から始まる添字によってアクセスさ
れる型定義の総称仮引数 

9.1 

| ʻ!!ʼ《Int32》 

0から始まる添字によってアクセスさ
れるメソッド定義の総称仮引数 

9.2 

| bool 

真理値。 

7.2 

background image

125 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

| char 

16ビットのUnicode符号点。 

7.2 

| class 《型参照》 

利用者定義の参照型。 

7.3 

| float32 

32ビット浮動小数点数。 

7.2 

| float64 

64ビット浮動小数点数。 

7.2 

| int8 

符号付き8ビット整数。 

7.2 

| int16 

符号付き16ビット整数。 

7.2 

| int32 

符号付き32ビット整数。 

7.2 

| int64 

符号付き64ビット整数。 

7.2 

| method 《呼出し規約》 《型》 ʻ*ʼ 
         ʻ(ʼ 《仮引数群》 ʻ)ʼ 

メソッドポインタ。 

14.5 

| native int 

32ビット又は64ビットの大きさがプラ
ットフォームに依存の符号付き整数。 

7.2 

| native unsigned int 

32ビット又は64ビットの大きさがプラ
ットフォームに依存の符号なし整数。 

7.2 

| object 

第4章のSystem.Objectを参照する。  

| string 

第4章のSystem.Stringを参照する。  

| 《型》 ʻ&ʼ 

《型》への管理下ポインタ。《型》は,
管理下ポインタ型又はtypedrefであ
ってはならない。 

14.4 

| 《型》 ʻ*ʼ 

《型》への管理外ポインタ。 

14.4 

| 《型》 ʻ<ʼ 《総称実引数列》  ʻ>ʼ 

総称型のインスタンス化 

9.4 

| 《型》 ʻ[ʼ [《範囲》 [ʻ,ʼ《範囲》]*] ʻ]ʼ 

省略可能な次元数及び省略可能な範囲
を指定した《型》の配列。 

14.1及び
14.2 

| 《型》 modopt ʻ(ʼ 《型参照》 ʻ)ʼ 

呼出し側によって無視してもよいカス
タム修飾子。 

7.1.1 

| 《型》 modreq ʻ(ʼ 《型参照》 ʻ)ʼ 

呼出し側が理解しなければならないカ
スタム修飾子。 

7.1.1 

| 《型》 pinned 

局所変数専用とする。ごみ集め子は,
参照された値を移動してはならない。 

7.1.1 

| typedref 

型付き参照(例えば,型
System.TypedReferenceの値。)は,
mkrefanyによって生成され,
refanytype又はrefanyvalによって使
用される。 

7.2 

| valuetype 《型参照》 

利用者定義の値型(ボックス化解除さ
れた状態。)。 

13 

| unsigned int8 

符号なし8ビット整数。 

7.2 

| unsigned int16 

符号なし16ビット整数。 

7.2 

| unsigned int32 

符号なし32ビット整数。 

7.2 

| unsigned int64 

符号なし64ビット整数。 

7.2 

| void 

無型。使用は,返却値の型又はvoid *
の一部としてだけ許可される。 

7.2 

状況によっては,文法は,型の規定のためにやや単純な表現の使用を許す。すなわち,“System.GC”

を,“class System.GC”の代わりに使用することができる。このような表現は,型指定と呼ばれる。 

《型指定》 ::= 

細分箇条 

  ʻ[ʼ [.module] 《ドット名》 ʻ]ʼ 

7.3 

| 《型参照》 

7.2 

| 《型》 

7.1 

7.1.1 

modreq及びmodopt 

background image

126 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

modreq(“必要な修飾子”)及びmodopt(“省略可能な修飾子”)を用いて定義されたカスタム修飾子は,

修飾子が宣言に附属されるのではなく,識別情報の一部となることを除いては,カスタム属性と同じとす

る(箇条21参照)。各修飾子は,識別情報項目に型参照を関連させる。 

CLI自体は,必す(須)修飾子と省略可能な修飾子とを同じように扱わなければならない。[必す(須)

又は省略可能な]カスタム修飾子の追加分だけが異なる二つの識別情報は,一致するとみなされてはなら

ない。カスタム修飾子は,VESの操作にその他の効果は及ぼさない。 

注記 根拠としては,必す(須)修飾子と省略可能な修飾子との相違が,メタデータを取り扱うCLI

以外のツール,典型的にはコンパイラ及びプログラム解析にとって重要なことによる。必す(須)

修飾子は,無視しないほうがよい修飾された項目への特殊な意味があることを示す。省略可能

な修飾子は,単に無視することができることを示す。 

例えば,Cプログラム言語のconst限定子は,const限定型仮引数をもつメソッドの呼出

し側が,それを特に扱う必要はないから,省略可能な修飾子でモデル化できる。他方,C++に

おいてコピー仮引数は,呼出し側が仮引数のコピーを作るので,必す(須)修飾子として定義

されたカスタム属性を使って印をつけなければならない。 

7.1.2 

アドレス固定(pinned) 

アドレス固定された(pinned)識別情報符号化は,局所変数を記述する識別情報中だけに現れなけれ

ばならない(15.4.1.3参照)。アドレス固定された局所変数を備えたメソッドが実行している間,VESは,

局所参照オブジェクトを再配置してはならない。すなわち,CLIの実装がオブジェクトを移動するごみ集

め子を使用する場合,ごみ集め子は,活性アドレス固定局所変数が参照するオブジェクトを移動してはな

らない。 

注記 根拠としては,管理外ポインタが管理下オブジェクトの参照をたぐるために使用された場合,

これらのオブジェクトはアドレス固定されていなければならないことによる。例えば,管理下

オブジェクトが,管理外データで操作するよう設計されたメソッドに渡された場合に,これは

起こる。 

7.2 

組込み型 

CLI組込み型は,基底クラスライブラリの中で定義された対応する値型をもつ。CLI組込み型は,識別

情報において,それらの特殊な符号化(すなわち,はん用なvaluetype《型参照》構文を使用しない符号化)

の使用によってだけ参照されなければならない。第1章は,組込み型を規定する。 

7.3 

利用者定義型(《型参照》)への参照 

利用者定義型は,型の完全名と解決有効範囲とを用いて参照されるか,又は同じモジュール中で型定義

が使用可能であれば,型定義を用いて参照される(箇条10参照)。 

《型参照》は,完全名及び解決有効範囲に対して使用される。 

《型参照》 ::= 
  [《解決有効範囲》] 《ドット名》 [ʻ/ʼ《ドット名》]* 

《解決有効範囲》 ::= 
  ʻ[ʼ .module 《ファイル名》 ʻ]ʼ 
| ʻ[ʼ 《アセンブリ参照名》ʼ]ʼ 

《アセンブリ参照名》 ::= 

細分箇条 

  《ドット名》 

5.1 

127 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

次の解決有効範囲は,入れ子でない型について規定している。 

− 現モジュール(及びアセンブリ)。これは,最もありふれた場合で,解決有効範囲が指定されていない

省略時の場合とする。定義が参照と同じモジュールにありさえすれば,型は,定義として解決されな

ければならない。 

注記 同じモジュール及びアセンブリ中の型を参照する型参照は,型定義を使用する方が,より良

く表現される。これが不可能(例えばcompilercontrolledというアクセス可能性の入れ

子型を参照する場合)か,又は,都合の悪いところ(例えば幾つかの1回パスのコンパイラ

中)では,型参照を,使用できる。 

− 異なるモジュール及び現アセンブリ。解決有効範囲は,構文的には記法[.module 《ファイル名》] を

使用することによって表現されたモジュール参照とする。参照されたモジュール(6.4参照)及び型(6.7

参照)が現アセンブリによって宣言されていて,その結果アセンブリの目録の中に登録されている場

合に限り,型は,定義として解決されなければならない。この場合,目録は,参照するモジュールで

物理的に保存されないことに注意する。 

− 異なるアセンブリ。解決有効範囲は,構文的には記法[《アセンブリ参照名》]で表現されたアセンブ

リ参照でなければならない。参照されたアセンブリは,現アセンブリのための目録中で宣言されなけ

ればならず(6.3参照),型は,参照されたアセンブリの目録の中で宣言されなければならない。また,

そのアセンブリから移出されるように,型が印付けされなければならない(6.7及び10.1.1参照)。 

− 入れ子型については,解決有効範囲は,常に取囲み型とする。(10.6参照)。構文的には,これは,入

れ子型の名前から取囲み型名を分けるために斜線(“/”)を使用することで示される。 

例 

基底クラスライブラリの中で定義された型System.Consoleは,mscorlibという名のアセン

ブリにある。 

     .assembly extern mscorlib { } 

     .class [mscorlib]System.Console 

現アセンブリでのxという名のモジュール中のC.Dという名の型への参照。 

     .module extern x 

     .class [.module x]C.D 

MyAssemblyという名前の,別のアセンブリでのFoo.Barという名の型の内部で入れ子になっ

ているCという名の型への参照。 

     .assembly extern MyAssembly { }  

     .class [MyAssembly]Foo.Bar/C 

7.4 

プラットフォーム固有なデータ型 

CLIの実装は,ある機能実行に必要なデータ型を規定する既存のオペレーティングシステム又は実行時

プラットフォーム上で行われることがある。メタデータは,CLI組込み型及び利用者定義型が,どのよう

にしてプラットフォーム固有なデータ型との間で組み換えられることになっているかを規定することによ

って,これらのプラットフォーム固有なデータ型との間での処理を可能にする。この組換え情報は,(キー

ワードmarshalを用いて)指定できる。 

− プラットフォーム固有なデータ型が実は返却され,指定されたCLIデータ型へ組み換えされなければ

ならないことを示すメソッドの返却値の型。 

− 呼出し側が提供するCLIデータ型が指定されたプラットフォーム固有データ型へ組み換えられなけれ

background image

128 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

ばならないということを示すメソッドへの仮引数。(仮引数が参照渡しである場合,更新される値は,

呼出しが完了するときに,プラットフォーム固有なデータ型からCLIデータ型の中へ組み換え戻され

なければならない。) 

− プラットフォームメソッドにオブジェクトを渡すどんな試みも,そのオブジェクトのコピーを作り,

フィールドを指定されたプラットフォーム固有データ型に取り替えなければならないことを示す利用

者定義型のフィールド。(オブジェクトが参照渡しである場合,呼出しが完了するときに,更新される

値は,組み換え戻されなければならない。) 

次に示す表は,CLIによって採用されるすべてのプラットフォーム固有な型及びそれらの記述を与える。

(より完全な記述は,これらの型を符号化するために使用される実際の値を提供する,第4章のenum 

System.Runtime.Interopservices.UnmanagedTypeの定義中で規定する。)0〜63までのすべての

符号化値は,CLIの既存の実装との後方互換性のために予約済みとする。値64〜127は,この規格及び関

連する規格で将来の使用するために予約済みとする。 

《プラットフォーム固有
型》::= 

記述 

クラスライブラリの
enum

UnmanagedTypeでの名
前 

ʻ[ʼ ʻ]ʼ 

プラットフォーム固有な配列。型及び大きさは,実
際に組み換えられた配列から実行時に決定される。 

LPArray 

| bool 

真理値とする。0でない値は真を表し,0は偽を表
す4バイトの整数値。 

Bool 

| float32 

32ビット浮動小数点数。 

R4 

| float64 

64ビット浮動小数点数。 

R8 

| [unsigned] int 

プラットフォーム上でポインタを保持できる符号
付き又は符号なし整数 

SysUInt又はSysInt 

| [unsigned] int8 

符号付き又は符号なしの8ビット整数 

U1又はI1 

| [unsigned] int16 

符号付き又は符号なしの16ビットの整数 

U2又はI2 

| [unsigned] int32 

符号付き又は符号なしの32ビットの整数 

U4又はI4 

| [unsigned] int64 

符号付き又は符号なしの64ビットの整数 

U8又はI8 

| lpstr 

ナル文字で終端したANSI 文字の配列へのポイン
タ。コードページは,実装固有とする。 

LPStr 

| lpwstr 

ナル文字で終端したUnicode文字の配列へのポイン
タ。文字符号化は,実装固有とする。 

LPWStr 

| method 

関数ポインタ。 

FunctionPtr 

| 《プラットフォーム固有型》 
ʻ[ʼ ʻ]ʼ 

《プラットフォーム固有型》の配列。長さは,実際
の組み換えられた配列の長さによって実行時に決
定される。 

LPArray 

| 《プラットフォーム固有型》 
ʻ[ʼ 《Int32》 ʻ]ʼ 

長さが《Int32》の《プラットフォーム固有型》の
配列。 

LPArray 

| 《プラットフォーム固有型》  
ʻ[ʼ  ʻ+ʼ 《Int32》 ʻ] ʼ 

実行時に要素の大きさが与えられる《プラットフォ
ーム固有型》の配列。《Int32》は,実行時に配列
の要素のバイトサイズを含む(仮引数番号0から数
える。)現メソッドへの仮引数を指定する。フィー
ルドではなくメソッドにだけ適用することができ
る。 

LPArray 

| 《プラットフォーム固有型》  
ʻ[ʼ 《Int32》 ʻ+ʼ 《Int32》 
ʻ]ʼ 

実行時に要素の大きさが与えられる《プラットフォ
ーム固有型》の配列。最初の《Int32》は,配列中
の要素の個数を指定する。第2の《Int32》は,ど

LPArray 

background image

129 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

の仮引数が,(仮引数番号0から数える。)現メソッ
ドに配列中に追加する要素の個数を指定するかを
指定する。フィールドではなくメソッドにだけ適用
することができる。 

例 

.method int32 M1( int32 marshal(int32), bool[] marshal(bool[5]) ) 

メソッドM1は,二つの実引数をとる。それらは,int32及び五つの真理値の配列とする。 

.method int32 M2( int32 marshal(int32), bool[] marshal(bool[+1]) ) 

メソッドM2は,二つの実引数をとる。それらは,int32及び真理値の配列とする。配列の中

の要素の個数は,最初の仮引数の値によって与えられる。 

.method int32 M3( int32 marshal(int32), bool[] marshal(bool[7+1]) ) 

メソッドM3は,二つの実引数をとる。それらは,int32及び真理値の配列とする。要素の個

数は,最初の仮引数の値に7を加えたもので与えられる。 

可視性,アクセス可能性及び隠ぺい 

第1章は,可視性及びアクセス可能性を規定する。メタデータは,これらの属性の他に,メソッド名隠

ぺいに関する情報を格納する。隠ぺいは,基底型から継承したどのメソッド名がコンパイル時の名前結合

に使用可能となるかを制御する。 

8.1 

最上位の型の可視性及び入れ子型のアクセス可能性 

可視性は,最上位の型にだけ付けられる。また,同じアセンブリ内の型にだけ見えるか,どのアセンブ

リからも見えるかの二つの可能性だけがある。入れ子型(すなわち,別の型のメンバの型)については,

型を参照することが可能なメソッドの組を更に洗練するアクセス可能性をもつ。入れ子型は,七つのアク

セス可能性モード(第1章参照)のどれでももてるが,それ自身の直接の可視属性はもたず,その代わり

に,取囲み型の可視性を代わりに使用する。 

最上位の型の可視性が,そのすべてのメンバの名前の可視性を制御するから,入れ子型は,それを取り

囲む型よりも可視にはなりえない。すなわち,取囲み型が,アセンブリ内にだけ可視である場合,アクセ

ス可能性publicを備えた入れ子型も,依然としてそのアセンブリ内だけで使用可能とする。対照的に,

アクセス可能性assemblyをもつ入れ子型は,取囲み型がアセンブリの外部で可視であっても,アセンブ

リ内での使用に制限される。 

すべての型の符号化を一貫性がありコンパクトにするために,最上位の型の可視性及び入れ子型のアク

セス可能性は,23.1.15の論理モデルと同じ機構を用いて符号化される。 

8.2 

アクセス可能性 

アクセス可能性は,メタデータ中で直接符号化される。例を22.26に示す。 

8.3 

隠ぺい 

隠ぺいは,型の個別メソッドに適用するコンパイル時の概念とする。CTS(共通型システム,第1章参

照)は,単一ビットによって,隠ぺいのための二つの機構のいずれかを指定する。 

− 名前による隠ぺい(hide-by-name)。これは,与えられた型への名前の導入が,同じ種類で同じ名前の

すべての継承されたメンバを隠ぺいすることを意味する。 

− 名前及び識別情報による隠ぺい(hide-by-name-and-sig)。与えられた型への名前の導入は,それが入れ

子型及びフィールドであるには,同じ種類であって,かつ,正確に同一の型であるすべての継承メン

130 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

バを隠ぺいし,それがメソッド,特性及びイベントであるには,同じ種類であって,かつ,正確に同

じ識別情報であるすべての継承メンバを隠ぺいすることを意味する。 

隠ぺいの実行時支援は,ない。CLIの規格合致合処理系は,すべての参照をあたかも名前が名前及び識

別情報による隠ぺいと印付けられるかのように扱う。名前による隠ぺいを望むコンパイラは,属性

newslot(15.4.2.3参照)でメソッド定義を印付け,メソッド参照(15.1.3参照)を解決するために使われ

る型を正確に選択することによって,それを実現できる。 

総称性 

第1章で示したとおり,総称性によって,パターンを用いて型及びメソッドのファミリ全体を定義する

ことが可能となる。ここでパターンとは総称仮引数と呼ばれる場所取りを含む。総称仮引数は必要に応じ

て指定された型に置き換えられ,ファミリの全メンバは実際に要求された型でインスタンス化される。例

えば,class List<T>{}はリストと成り得る全ファミリを表現する。すなわち,List<string>, 

List<int>及びList<Button>は三つの有効なインスタンス化を表す。しかし,次で示すとおり,CLS

合致の名前では,これらの型はclass List̀1<T>{},List̀1<string>,List̀1<int>,及び

List̀1<Button>となる。 

総称型はC<T>のように名前に引き続く<…>で区切られた総称仮引数からなる。同一有効範囲内において,

二つ以上の総称型を,同じ名前ではあるが異なる数の総称仮引数を用いて定義してはならない。しかし,

総称仮引数の個数に関するこのような意味での多重定義をソース言語レベルでは許容するために,CLS規

則43では,複数の総称型名を一意なCIL名に対応付けを定義している。この規則は,CLS合致の名前で

は,一つ以上の総称仮引数をもつ型Cは,̀nという形式の接尾辞をもたなければならないと定めている。

ここでnは(先行するゼロをもたない)十進整定数であり,Cがもつ総称仮引数の個数を表現する。例え

ば,型C,C<T>,及びC<K,V>は,CLS合致の名前では,それぞれC,C̀1<T>,及びC̀2<K,V>となる。 

注記 すべての標準ライブラリはCLS合致の名前をもつ。例えば 

System.Collections.Generic.IEnumerablè1<T>。 

総称性について詳細な議論に移る前に,幾つかの新しい用語を次で定義する。 

− public class List̀1<T> {} は総称型定義とする。 

− <T> は総称型並びとし,Tは総称仮引数とする。 

− List̀1<T> は総称型とする。これは,少なくとも一つ総称仮引数をもつため,開型又は開総称型と

呼ばれることがある。本章では開型という用語を用いる。 

注記 訳注:対応国際規格に誤りがあったため総称型を開型に訂正した。 

− List̀1<int> は,もはや非束縛総称仮引数をもたないため,閉総称型とする。(これは,インスタ

ンス化された総称型又は総称型インスタンス化と呼ばれることがある。)この章では,閉型という用語

を用いる。 

− 総称性は,厳密に開でも厳密に閉でもない総称型を含むことに注意する。次の例における基底クラス

Bが,厳密に開でも,厳密に閉でもない例である。. public class B̀2<T,U> {}が与えられた下

での. public class D̀1<V> extends B̀2<!0,int32> {}。 

− 総称型と通常の型との区別が必要な場合,後者を総称でない型と呼ぶ。 

− <int> は,総称実引数並びとし,intは総称実引数とする。 

− この規格では,総称仮引数と総称実引数とを区別する。可能であれば,List̀1<int>について語る

場合,“intは総称仮引数Tに使われた型である。”という表現を用いる。(自己反映計算においては,

131 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

このような場合“Tはintに束縛される。”といわれることがある。) 

− “(C1, …, Cn) T”は総称仮引数Tに対する総称仮引数制約とする。 

注記 次の定義を考える。 

class C̀2<(I1,I2) S, (Base,I3) T> { … } 

これは二つの総称仮引数S及びTをもつ,Cと呼ばれるクラスを表現している。Sは二つの

インタフェースI1及びI2を実装するよう制約が課されている。TはクラスBaseから導出する

よう制約が課されるとともに,インタフェースI3を実装するよう制約が課されている。 

総称型定義内において,総称仮引数はその添字によって参照される。総称仮引数ゼロは,!0として,総

称仮引数1は!1として,という具合に参照される。同様に総称メソッド定義本体内において,総称仮引

数はその添字によって参照される。総称仮引数ゼロは,!!0として,総称仮引数1は!!1として,という

具合に参照される。 

9.1 

総称型定義 

総称型定義は総称仮引数を含むものとする。各総称仮引数は,名前及び省略可能な制約の集合をもつこ

とができる。ここで制約とは,総称実引数が代入互換でなければならないような型とする。省略可能な異

なる記法も認められている(10.1.7参照)。(次で用いられる!及び!!記法の説明に関しては9.4参照)総称

仮引数は,次の宣言の有効範囲の中に存在する。 

− 制約の中(例 . class … C̀1<(class IComparablè1<!0>) T>) 

− 型に基づく定義が導出する任意の基底クラス(例 .class … MultiSet̀1<T> extends class 

Set̀1<!0[]>) 

− 型に基づく定義が実装する任意のインタフェース(例 .class … Hashtablè2<K,D> implements 

class IDictionarỳ2<!0,!1>) 

− すべてのメンバ(インスタンスフィールド及び静的フィールド,メソッド,構築子,特性,並びにイ

ベント)ただし,入れ子クラスである場合を除く。 

注記 C#では囲みクラスから入れ子クラスで用いられるために,総称仮引数を許可している。しかし,

この場合,必要とする付加的な任意の総称仮引数をメタデータの囲みクラス定義に加える。 

総称型定義は静的メソッド,インスタンスメソッド,及び仮想メソッドを含んでもよい。 

総称型定義は,次の制限を受ける。 

− 総称仮引数は,それ単独では,基底クラス又は任意の実装されたインタフェースを指定するために用

いることはできない。したがって,例えば,.class … G̀1<T> extends !0 は不当となる。しか

し,別の総称型の入れ子になっている場合,基底クラス又はインタフェースに総称仮引数を用いるこ

とは妥当となる。例えば,.class … G̀1<T> extends class H̀1<!0>及び.class … G̀1<T> 

extends class B̀2<!0,int32>はともに妥当となる。 

注記 この根拠は次のとおりとする。この制限によって総称型はインスタンス化時ではなく定義時

に妥当かどうかを判定できる。例えば,.class … G̀1<T> extends !0,において,どの

メソッドがどのメソッドを上書きするのかは分からない。なぜならば基底クラスに関する情

報は何も与えられていないからである。実際,Tがクラスであるかどうかすら分からない。

それは配列かもしれないし,又はインタフェースかもしれない。同様に,.class … 

C̀2<(!1)T,U>についても,基底クラス又はインタフェース定義に関する情報が何もないと

いう意味で,同じ状況にある。 

− varargメソッドは,総称型のメンバになることはできない。 

132 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

注記 この根拠は次のとおりである。これを制限とせずに実装するのは,非常に困難であろう。vararg

はCLIが対象とする言語の中で,非常に限られた範囲だけで使用されるため,総称型から

varargメソッドを除外することとした。 

− 総称仮引数を無視したとき,継承及びインタフェースの階層構造には,循環があってはならない。よ

り正確には,節が総称であってもよい(その場合,開の)クラス及びインタフェースであり,辺が次

で指定されるようなグラフとして定義する。 

− (総称であってもよい)クラス又はインタフェースDがクラス又はインタフェースBを拡張する又

は実装する場合,DからBへ辺を追加する。 

− (総称であってもよい)クラス又はインタフェースDがインスタンス化されたクラス又はインタフ

ェースB<type-1, …, type-n>を拡張する又は実装する場合,DからBへ辺を追加する。 

− このグラフが循環を含まない場合妥当とする。 

注記 本アルゴリズムは,総称でない型に対する規則の自然な一般化となっている(第1章 8.9.9参

照)。 

9.2 

総称性及び再帰的継承グラフ 

注記 継承グラフは直接的に循環することはないが,親クラス又は親インタフェースから与えられイ

ンスタンス化されたものは,直接的又は間接的に循環依存関係になることがある。これらは,

許されるものもあれば(例C : IComparable<C>)許されないものもある(例 class B<U>

が与えられた下でのclass A<T> : B<A<A<T>>>)。 

各型定義は,有限インスタンス化閉包を生成しなければならない。インスタンス化閉包は次で定義され

る。 

1) 単一の総称型定義を含む集合を生成する。 

2) 上記の集合に次の条件を満たす総称型を加えていくことによって閉包を構成する。その条件とは,

その集合に含まれるすべての型の基底クラス及び実装されたインタフェースの型識別情報に参照さ

れるすべての総称型とする。この集合に入れ子になったインスタンス化を含める。したがって,参

照型Stack<List<T>>は実際には,List<T> 及びStack<List<T>>の両方として数える。 

3) 次のグラフを構築する。 

− 節はその集合の中の型の形式的な型仮引数とする。名前衝突を避けるために,必要に応じてラム

ダ計算のアルファ変換に相当する名前変換を用いる。 

− Tが,参照される型D<…, U, …>のUに置換される実際の型実引数として現れる場合,TからU

への展開しない辺(->)を付加する。 

− Tが,参照される型D<…, U, …>のUに置換される実際の型実引数のどこか内部に(ただし,型

実引数そのものとしてではなく)現れる場合,TからUへの展開する辺(=>)を付加する。 

展開する循環とは,少なくとも一つの展開する辺(=>)を含むインスタンス化閉包の中にある循環とする。

ここで定義した系のインスタンス化閉包が有限であることと,上記で構築されたグラフが展開する循環を

含まないこととは同値とする。 

例 

class B<U> 

class A<T> : B<A<A<T>>> 

上記の二つのクラスは(展開する辺=>及び展開しない辺->を用いて)次の辺を生成する。 

T  ->   T   (参照される型A<T>によって生成される。) 

133 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

T  =>  T   (参照される型A<A<T>>によって生成される。) 

T  =>  U   (参照される型B<A<A<T>>>によって生成される。) 

このグラフは,展開する循環を含むため,インスタンス化閉包は無限となる 。 

例 

class B<U> 

class A<T> : B<A<T>> 

上記のクラスは次の辺を生成する。 

T -> T (参照される型 A<T>によって生成される。) 

T => U (参照される型B<A<T>>によって生成される。) 

このグラフは,展開する循環を含まないため,インスタンス化閉包は有限となる。 

例 

class P<T> 

class C<U,V> : P<D<V,U>> 

class D<W,X> : P<C<W,X>> 

上記のクラスは次の辺を生成する。 

U -> X   V -> W   U => T   V => T (参照される型D<V,U>及びP<D<V,U>>によって生成さ

れる。) 

W -> U   X -> V   W => T   W => T (参照される型C<W,X>及びP<C<W,X>>によって生成さ

れる。) 

このグラフは,展開しない循環を含む(例えばU -> X -> V -> W -> U)が,展開する循環を含

まないため,インスタンス化閉包は有限となる。 

9.3 

総称メソッド定義 

総称メソッド定義とは,総称仮引数並びを含むメソッド定義とする。総称メソッドは,総称でない型の

中に定義することも,総称型の中に定義することもできる。後者の場合,メソッドの総称仮引数は,その

所有者 の総称仮引数に付加されていなければならない。総称型定義である場合と同様,総称メソッド定義

上の各総称仮引数は,名前及び省略可能な制約の集合をもつ。 

注記 訳注:所有者の定義は第2章22.20参照。 

総称メソッドは,静的,インスタンス,又は仮想のいずれであってもよい。クラス構築子又はインスタ

ンス構築子(それぞれ.cctor又は.ctor)は,総称であってはならない。 

メソッドの総称仮引数は,識別情報及びメソッド本体の中,並びに総称仮引数制約の中をその有効範囲

とする。 

注記 この識別情報はメソッドの返却値型を含む。次の例で示す。 

.method … !!0 M̀1<T>() { … } 

!!0は有効範囲にある。それは,宣言内のその仮引数に先行するにもかかわらず,M̀1<T>

の総称仮引数である。 

総称インスタンスメソッド(仮想及び仮想でないを問わない)は,総称型のメンバとして定義できるが,

この場合,総称型及び総称メソッドの両方の総称仮引数は,メソッド識別情報及びメソッド本体の中,並

びにメソッド総称仮引数の制約の中をその有効範囲とする 

9.4 

総称型のインスタンス化 

《総称実引数群》は総称実引数並びを表現するために用いられる。 

background image

134 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

《総称実引数群》::= 

  《型》   [ʻ,ʼ  《型》 ] 

型が総称仮引数を含まない場合,型は閉とする,そうでなければ開とする。 

総称型定義が与えられたとき,インスタンス化された型を生成するために,総称型定義を総称実引数を

用いてインスタンス化することができる。 

例 

総称クラスMyList及び値型Pairに対する適切な定義が与えられているものとすると,これ

らを次のとおりインスタンス化することができる。 

newobj instance void class MyList̀1<int32>::.ctor() 

initobj valuetype Pair̀2<int32, valuetype Pair<string,int32>> 

例 

ldtoken !0 

// !0 = generic parameter 0 in generic 

type definition 

castclass class List̀1<!1> 

// !1 = generic parameter 1 in generic 

type definition 

box !!1 

// !!1 = generic parameter 1 in generic 

method definition 

インスタンス化における総称実引数の個数は,型定義又はメソッド定義において指定される総称仮引数

の個数と一致しなければならない。 

CLIでは,総称型の部分的なインスタンス化を提供していない。さらに,総称型は,メタデータ識別情

報のblob内では,いかなる箇所でもインスタンス化されないまま現れてはならない。 

次の種類の型は,(総称型又は総称メソッドの)インスタンス化において実引数として用いることはでき

ない。 

− Byref型(例 System.Generic.Collection.List̀1<string&> は妥当ではない。) 

− CIL評価スタックの中を指すことが可能なフィールドを含む値型 

(例 List<System.RuntimeArgumentHandle>) 

− void(例 List<System.Void>は妥当ではない。) 

管理外ポインタ型(例 int32*)は,総称型及び総称メソッドの総称実引数として用いることができ

る。 

注記 根拠は次のとおりである。Byref型が総称実引数として使用できないのは,幾つかの,実際には

ほとんどの,インスタンス化が妥当でないためである。例えば,byrefは,フィールド型又はメ

ソッド返却値の型に使うことができないため,List̀1<string&> の定義において,型!0を

もつフィールド又は!0の型を返すメソッドのいずれも宣言することができない。 

インスタンス化された型のオブジェクトは,その厳密な型を実行時に再現するために十分な情報(型及

びその総称実引数の個数を含む)をもち合わせていなければならない。 

注記 根拠は次のとおりである。この制約は,自己反映計算 (System.Object::GetType)の場合と

同様,キャスト及びインスタンス検査を正しく実装するために要請されている。 

9.5 

総称における変性 

CLIは,インタフェース及び委譲クラスの識別情報においてだけ,総称仮引数の共変性及び反変性を提

供する。 

135 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

記号“+”は,10.1.7の構文で用いられ,共変性総称仮引数を示すために用いられるのに対し,“-”は,

反変性総称仮引数を示すために用いられる。 

注記 ここから参考情報であり規定ではない。 

総称インタフェースがあるとし,例えばIÀ1<+T>のように,その一つの総称仮引数が共変的であると

する。このとき,代入互換性の記法を用いて,GenArgB := GenArgA である場合に限り,すべてのイン

スタンス化は,IÀ1<GenArgB> := IÀ1<GenArgA>を満足する。したがって,例えば,型IÀ1<string>

のインスタンスは,型IÀ1<object>をもつ局所変数に代入することができる。 

総称における反変性は,逆の意味合いで作用する。反変的なインタフェースIB̀1<-T>があるとすると, 

GenArgA := GenArgBである場合に限り,IB̀1<GenArgB> := IB̀1<GenArgA>を満足する。 

例 (構文は例示的に高水準言語のものを用いている。) 

// Covariant parameters can be used as result types 

interface IEnumerator<+T> { 

 T Current { get; } 

 bool MoveNext(); 

// Covariant parameters can be used in covariant result types 

interface IEnumerable<+T> { 

 IEnumerator<T> GetEnumerator(); 

// Contravariant parameters can be used as argument types 

interface IComparer<-T> { 

 bool Compare(T x, T y); 

// Contravariant parameters can be used in contravariant interface types 

interface IKeyComparer<-T> : IComparer<T> { 

 bool Equals(T x, T y); 

 int GetHashCode(T obj); 

// A contravariant delegate type 

delegate void EventHandler<-T>(T arg); 

// No annotation indicates non-variance.  Non-variant parameters can 

be used anywhere. 

// The following type shall be non-variant because T appears in as a 

method argument as 

// well as in a covariant interface type 

interface ICollection<T> : IEnumerable<T> { 

 void CopyTo(T[] array, int index); 

 int Count { get; } 

注記 参考情報終わり 

136 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

9.6 

インスタンス化された型の代入互換性 

代入互換性については,第1章8.7で定義されている。 

例 

Employee := Managerと仮定する。 

IEnumerable<Manager> eManager = ... 

IEnumerable<Employee> eEmployee = eManager;  

     // 

Covariance  

IComparer<object> objComp = ... 

IComparer<string> strComp = objComp;  

     // 

Contravariance  

EventHandler<Employee> employeeHandler = ... 

EventHandler<Manager> managerHandler = employeeHandler; // 

Contravariance 

例 次が与えられているとする。 

interface IConverter<-T,+U> { 

  U Convert(T x); 

IConverter<string, object> := IConverter<object, string>となる。 

次が与えられているとする。 

delegate U Function<-T,+U>(T arg); 

Function<string, object> := Function<object, string>となる。 

例 

IComparer<object> objComp = ... 

// Contravariance and interface inheritance 

IKeyComparer<string> strKeyComp = objComp; 

IEnumerable<string[]> strArrEnum = … 

// Covariance on IEnumerable and covariance on arrays 

IEnumerable<object[]> objArrEnum = strArrEnum; 

IEnumerable<string>[] strEnumArr = ... 

// Covariance on IEnumerable and covariance on arrays 

IEnumerable<object>[] objEnumArr = strEnumArr; 

IComparer<object[]> objArrComp = ... 

// Contravariance on IComparer and covariance on arrays 

IComparer<string[]> strArrComp = objArrComp; 

IComparer<object>[] objCompArr = ... 

// Contravariance on IComparer and covariance on arrays 

IComparer<string>[] strCompArr = objCompArr; 

9.7 

メンバ識別情報の妥当性 

型安全性を保証するため,共変性総称型及び反変性総称型のメンバの識別情報が整形式となるには,更

なる要請を課す必要がある。 

137 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

注記 ここから参考情報であり規定ではない。 

− 共変性仮引数は,型定義における生産側(producer),読込み側(reader)又は取得側(getter)位置に

だけ現れることができる。すなわち,次の箇所とする。 

− メソッドの返却値の型 

− 継承されたインタフェース 

− 反変性仮引数は,消費側(consumer),書出し側(writer),又は設定側(setter)位置にだけ現れること

ができる。すなわち,次の箇所とする。 

− メソッドの実引数型 

− 変性のない仮引数はどこに現れてもよい。 

注記 参考情報終わり 

ここで,共変性総称型定義及び反変性総称型定義が妥当となるとは何を意味するかを,形式的に定義す

る。 

総称型定義: 総称型定義G<var̲1 T̲1, …, var̲n T̲n> は,次の場合に妥当とする。Gがインタフェー

ス,又は委譲型,かつ,S = <var̲1 T̲1, …, var̲n T̲n>に対して,次の各々が成り立つ場合に妥当とする。

ここでvar̲n は,+,-,又はなしのいずれかとする。 

− 各インスタンスメソッド及び仮想メソッド宣言は,Sに対して妥当となる。 

− 各継承されたインタフェース宣言は,Sに対して妥当となる。 

− 静的メンバ,インスタンス構築子,又は型自身の総称仮引数制約に対する制限がない。 

注釈付きの総称仮引数S = <var̲1 T̲1, …, var̲n T̲n>が与えられているものとする。ここでは,型定義の

各種構成要素が,Sに関して妥当となるとは何を意味するかを定義する。反転演算は-Sと書き,“負を正に

反転すること及び正を負に反転すること”を意味すると定義する。 

次を考慮する。 

− “Sに関して妥当となる”は“共変性に振る舞う”と同義となる。 

− “-Sに関して妥当となる”は“反変性に振る舞う”と同義となる。 

− “S及び-Sに関して妥当となる”は“変性なく振る舞う”と同義となる。 

この最後の定義によって,型を共変性仮引数及び反変性仮引数にすることを禁止する効果があることに

注意する。すなわち,すべての総称仮引数の出現は,変性なしでなければならない。 

メソッド: メソッド識別情報t meth(t̲1,…,t̲n) は,Sに対して,次のいずれかの場合妥当とする。 

− その返却値の型識別情報tがSに関して妥当とし,かつ 

− 各実引数型識別情報tが-Sに関して妥当とする。 

− 各メソッド総称仮引数制約型t̲jが-Sに関して妥当とする。 

注記 言い換えれば,返却値は共変性に振る舞い,実引数は反変性に振る舞う。総称仮引数に対する

制約も反変性に振る舞う。 

型識別情報 型識別情報tは,次のいずれかの場合にSに関して妥当となる。 

− 総称でない型(例 通常のクラス又は値型) 

− 総称仮引数T̲i。ただし,var̲iが+又はなしである場合(すなわち,総称仮引数であって共変性又は変

化性なしと印付けされたもの) 

− 配列型u[]であって,かつ,uがSに関して妥当なもの。つまり配列型は共変性をもって振る舞う。 

− 閉総称型G<t̲1,…,t̲n> であって,次を満たすもの 

− t̲iがSに関して妥当なもの。ここでGのi番目の仮引数は共変性で宣言されているものとする。 

138 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

− t̲iが-Sに関して妥当なもの。ここでGのi番目の仮引数は反変性で宣言されているものとする。 

− t̲iがSに関して及び-Sに関して妥当なもの。ここでGのi番目の仮引数は変化性なしで宣言されて

いるものとする。 

9.8 

識別情報及び結合 

総称型のメンバ(フィールド及びメソッド)は,メタデータトークンを用いてCIL命令で参照される。

ここでメタデータトークンは,表MemberRef(22.25参照)の入口を指定する。抽象的には,参照は次の

二つの部分からなる。 

1) メンバが宣言された型。この場合,インスタンス化された総称型定義。例 IComparer̀1<String> 

2) メンバの名前及び(インスタンス化されていない)総称識別情報。例 int32 Compare(!0,!0) 

インスタンス化されたときに,異なるメンバが同一の型をもつことは許されるが,MemberRefによって

区別することができる。 

例 

.class public C̀2<S,T> { 

  .field string f 

  .field !0 f 

  .method instance void m(!0 x) {...} 

  .method instance void m(!1 x) {...} 

  .method instance void m(string x) {...} 

閉型C̀2<string,string>は妥当とする。これはすべて同じ仮引数型でmと名前付けられた

三つのメソッド及び同じ型でfと名前付けられた二つのフィールドをもつ。これらは上記の

MemberRef符号化を通してすべて区別される。 

string C̀2<string, string>::f 

!0  C<string, string>::f 

void C̀2<string, string>::m(!0) 

void C̀2<string, string>::m(!1) 

void C̀2<string, string>::m(string) 

プログラム記述言語がこの種の多重定義をどのように解決するかは,各言語に委ねられた問題

とする。例えば,多くの言語では,この種の多重定義は禁止している。 

9.9 

継承及び上書き 

メンバ継承は第1章“メンバ継承”で定義されている。(上書き及び隠ぺいは,同じく第1章“隠ぺい,

上書き,及び配置”で定義されている。)この定義は,総称型に対応して自然な方法で拡張される。特に,

あるメンバが,基底クラス若しくは基底インタフェースから,(静的メンバ若しくはインスタンスメンバに

ついては)メンバを隠ぺいするかどうか,又は(仮想メソッドについては)メンバを上書きするかどうか

を決定するためには,単に各総称仮引数をその総称実引数で置き換え,結果として生成されるメンバ識別

情報を比較する。 

例 次でこの点について説明する。 

次の基底クラスB及び派生クラスDの定義を仮定する。 

.class B  

{ .method public virtual void V(int32 i) { … } } 

139 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

.class D extends B 

{ .method public virtual void V(int32 i) { … } } 

クラスD内で,D.Vは継承されたメソッドB.Vを上書きする。なぜならばそれらの名前と識別

情報が一致するからである。 

この単純な例が,総称型に対応してどのように拡張されるかを見ることにする。また,クラス

Dは,どの総称インスタンス化されたクラスから派生されるかを見ることにする。次の例を考え

る。 

.class B̀1<T> 

{ .method public virtual void V(!0) { … } } 

.class D extends B̀1<int32> 

{ .method public virtual void V(int32) { … } } 

.class E extends B̀1<string> 

{ .method public virtual void V(int32) { … } } 

クラスDはB<int32>から派生される。さらに,B<int32>は,次のメソッドを定義する。 

   public virtual void V(int32 t) { … } 

ここでBの総称仮引数Tを,特定の総称実引数int32で置き換え単純化している。これはメ

ソッドD.Vと(同じ名前及び識別情報であり)一致している。したがって,上記の総称型でない

場合の例と同じ理由によって,D.Vは継承メソッドB.Vを上書きする。 

この例とB<string>から派生されたクラスEとを対比する。こちらの場合,BのTをstring

で置き換えることで,B.Vは次の識別情報を得る。 

   public virtual void V(string t) { … } 

この識別情報は,メソッドE.Vとは異なるため,基底クラスのB.Vメソッドを上書きするこ

とはない。 

型定義が不当となるのは,基底クラスの総称実引数を置換した後,二つのメソッドが同じ名前及び同じ

識別情報(返却値型を含む)となるときとする。次でこの点について説明する。 

例 

.class B̀1<T> 

{ .method public virtual void V(!0 t)     { … } 

  .method public virtual void V(string x) { … } 

.class D extends B̀1<string> { } // Invalid 

クラスDは,B<string>から継承する二つのメソッドが同一の識別情報void V(string)と

なるので,不当となる。 

しかし,次のDは妥当となる。 

.class D extends B̀1<string> 

{ .method public virtual void  V(string t)  

{ … } 

  .method public virtual void  W(string t) 

  { … 

    .override  method instance void class B̀1<string>::V(!0) 

    … 

140 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

  } 

総称メソッド(すなわち,それ自身の総称仮引数をともなうメソッド)を上書きする場合,総称仮引数

の個数は,上書きされるメソッドの総称仮引数の個数と完全に一致しなければならない。上書きされる総

称メソッドが,総称実引数に対する一つ以上の制約をもつ場合,次のことが言える。 

− 上書きするメソッドは,同じ総称実引数に対してだけ制約をもつことができる。 

− 総称実引数に対して上書きするメソッドによって指定される総称実引数に対する制約は,同じ総称実

引数に対して,上書きされるメソッドによって指定される制約よりも強いものであってはならない。 

注記 上書きするメソッド本体の中で,その識別情報に直接指定される制約だけが適用できる。メソ

ッドが呼び出される場合,call又はcallvirt命令内のメタデータトークンに関連付けられた制約

が,効力をもつ。 

9.10 明示的なメソッドの上書き 

型は,総称型であるかどうかにかかわらず,明示的な上書きを用いて,特定の仮想メソッドを(そのメ

ソッドがインタフェース又は基底クラスのいずれによって導入されたかにかかわらず。)実装することがで

きる(10.3.2及び15.1.4参照)。 

上書きを司るこの規則は,総称型に対応して次のとおり拡張される。 

− 実装するメソッドが総称でない型の一部,又は閉総称型の一部の場合,宣言するメソッドは,その型

の基底型の一部又はその型で実装されたインタフェースの一部でなければならない。 

例 

.class interface Ì1<T> 

{ .method public abstract virtual void M(!0) {} 

.class C implements class Ì1<string> 

{ .override method instance void class Ì1<string>::M(!0) with  

  

method instance void class C::MInC(string) 

  .method virtual void MInC(string s) 

  { ldstr "I.M" 

    call void [mscorlib]System.Console::WriteLine(string) 

    ret 

  } 

− 実装する型が総称型の場合,宣言されるメソッドは,総称型でなければならず,かつ同じ個数のメソ

ッド総称仮引数をもたなければならない。 

実装するメソッド及び宣言されるメソッドのいずれも,インスタンス化された総称メソッドであって

はならない。これは,インスタンス化された総称メソッドが,インタフェースメソッドを実装するた

めに用いることができないことを意味する。さらに,総称メソッドを特定の総称仮引数でインスタン

ス化する特別なメソッドを提供することができないことも意味する。 

例 次が与えられているとする。 

  .class interface I 

{ .method public abstract virtual void M<T>(!!0) {} 

141 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

  .method public abstract virtual void N() {} 

次のいずれの.override文も許されない。 

.class C implements class Ì1<string> 

{ .override class I::M<string> with instance void class C::MInC(string) 

  .override class I::N with instance void class C::MyFn<string> 

  .method virtual void MInC(string s) { … } 

  .method virtual void MyFn<T>() { … } 

9.11 総称仮引数に対する制約 

総称クラス又は総称メソッドで定義された総称仮引数は,一つ以上の型(符号化については,22.21表

GenericParamConstraint参照)及び一つ以上の特別な制約(10.1.7)による制約が課されている。総称仮引

数は,宣言された各制約に対し(ボックス化されたときに)代入互換性をもち,かつ指定されたすべての

特別な制約を満たす総称実引数によってだけインスタンス化されることができる。 

総称仮引数制約は,総称型定義自身又は総称メソッド定義自身と少なくとも同一の可視性をもたなけれ

ばならない。 

注記 総称仮引数に対するこれら以外の制限は存在しない。特に,次の使用は妥当とする。総称クラ

スの総称仮引数に対する制約は,その総称仮引数に対して,更に,そのクラスそれ自身に対し

ても,再帰的な参照を構成してよい。 

.class public Set̀1<(class IComparable<!0>) T> { … } 

// can only be instantiated by a derived class! 

.class public C̀1<(class C<!0>) T> {} 

.class public D extends C̀1<class D> { … } 

総称メソッドの総称仮引数に対する制約は,総称メソッド及び(総称であれば)その囲みク

ラスの両方の総称仮引数に対する再帰的な参照を構成することができる。その制約は,囲みク

ラス自身を参照することもできる。 

.class public À1<T> { 

  .method public void M<(class IDictionary<!0,!!0>) U>() {} 

総称仮引数制約は,総称仮引数であっても,配列のように総称でない型であってもよい。 

.class public List̀1<T> { 

  // The constraint on U is T itself 

  .method public void AddRange<(!0) U>(class IEnumerablè1<!!0> items) 

{ … } 

総称仮引数は複数の制約をもつことができ,多くても一つの基底クラスから継承され(何も制約が指定

されない場合,CLIは省略時解釈として System.Objectから継承され),更に,ゼロ個以上のインタフ

ェースを実装することができる。(クラス又はメソッドに制約を用いる場合の構文は,10.1.7で定義され

る。) 

例 

background image

142 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

次の宣言は,総称クラスOrderedSet<T>を示している。ここで総称仮引数Tは,クラス

Employeeから継承されるとともに,インタフェースIComparable<T>を実装するように制約付

けされている。 

.class OrderedSet̀1<(Employee, class 

[mscorlib]System.IComparablè1<!0>) T> { … } 

注記 総称仮引数に対する制約は,総称仮引数がインスタンス化される可能性のある型だけを制限す

る。正当性検証(3章参照)では,総称仮引数が制約に一致するように提供されると分かって

いるようなフィールド,特性,又はメソッドに対して,最初にボックス化(3章参照)されて

いる場合又はcallvirt命令がconstrained.接頭辞命令(3章参照)で前置修飾されている

場合を除き,総称仮引数を通して,それらを直接アクセスすることも,呼び出すこともできな

いことを要請している。 

9.12 総称型のメンバへの参照 

注記 この細分箇条は参考情報とする。 

型メンバを参照するCIL命令は,インスタンス化された型のメンバへの参照を許可するように一般化さ

れる。 

参照の中で指定された総称実引数の個数は,型の定義で指定された数と一致しなければならない。 

メソッドを参照するCIL命令は,インスタンス化された総称メソッドへの参照が許可されるように一般

化される。 

10 型の定義 

型(すなわち,クラス,値型及びインタフェース。)は,モジュールの最上位で定義できる。 

《宣言》 ::= 

箇条 

  .class 《クラスヘッダ》 ʻ{ʼ 《クラスメンバ》* ʻ}ʼ 

10 

| … 

この宣言によって生成された論理的なメタデータ表は,22.37で規定される。 

注記 根拠としては,歴史上の理由で,構文要素の多くが,名前中に“型”の代わりに“クラス”を

型の定義に誤用していることによる。すべてのクラスは型であるが,“型”は,値型及びインタ

フェースを包含する上位語とする。 

10.1 型ヘッダ(《クラスヘッダ》) 

型ヘッダは,次の五つから構成される。 

− 任意個の型属性。 

− 省略可能な総称仮引数。 

− 名前(《識別子》)。 

− 省略時には,[mscorlib]System.Objectになる基底型(又は基底クラス型)。 

− この型及びそのすべての子孫型がその契約を満たさなければならない省略可能なインタフェースの並

び。 

《クラスヘッダ》 ::= 
  《クラス属性》* 《識別子》[ʻ<ʼ 《総称仮引数》 ʻ>ʼ] [extends 《型指定》] [implements 
《型指定》 [ʻ,ʼ 《型指定》]*] 

任意の総称仮引数は,総称型を定義する場合に使用される(10.1.7参照)。 

キーワードextendsは,型の基底型を規定する。型は,厳密に一つの他の型から拡張しなければなら

background image

143 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

ない。型が指定されていなければ,ilasmは,型をSystem.Objectから継承させるためにextend節を

加える。 

キーワードimplements は,型のインタフェースを規定する。インタフェースをここで一覧表示する

ことによって,型は,すべての具体的な実装が,インタフェースが宣言するあらゆる仮想メソッドの実装

を提供することを含め,そのインタフェースの契約を守ることを宣言する(箇条11及び12参照)。 

例 (参考): 

このコードは,クラスCounterTextBoxを宣言する。それは,アセンブリ

System.Windows.Formsの中のクラスSystem.Windows.Forms.TextBoxを拡張し,現ア

センブリのモジュールCounter中のインタフェースCountDisplayを実装する。属性private,

属性auto及び属性autocharは,10.1.1〜10.1.6に記述される。 

.class private auto autochar CounterTextBox 

   extends [System.Windows.Forms]System.Windows.Forms.TextBox 

   implements [.module Counter]CountDisplay 

{ // クラスの本体 

型は,カスタム属性を幾つでも添付することができる。箇条21で規定されるように,カスタム属性が添

付される。型の他の(あらかじめ定義済みの)属性は,可視性を指定する属性,型配置情報,型意味情報,

継承規則,相互運用情報及び特殊扱いについての情報へグループ化することができる。10.1.1〜10.1.6は,

あらかじめ定義された属性の各グループに関する追加情報を提供する。 

《クラス属性》 ::= 

記述 

箇条又は
細分箇条 

  abstract 

型は抽象とする。 

10.1.4 

| ansi 

ANSIとしてプラットフォームへ文字列を組み換える。 10.1.5 

| auto 

フィールドの配置が自動的に供給される。 

10.1.2 

| autochar 

ANSI又はUnicode(プラットフォームに依存)として
プラットフォームへ文字列を組み換える。 

10.1.5 

| beforefieldinit 

静的メソッドが呼び出される前に,型を初期化するこ
とは不要とする。 

10.1.6 

| explicit 

フィールドの配置は,明示的に供給される。 

10.1.2 

| interface 

インタフェースを宣言する。 

10.1.3 

| nested assembly 

入れ子型のためのアセンブリのアクセス可能性。 

10.1.1 

| nested famandassem 

入れ子型のためのファミリ及びアセンブリのアクセス
可能性。 

10.1.1 

| nested family 

入れ子型のためのファミリのアクセス可能性。 

10.1.1 

| nested famorassem 

入れ子型のためのファミリ又はアセンブリのアクセス
可能性。 

10.1.1 

| nested private 

入れ子型のための非公開のアクセス可能性。 

10.1.1 

| nested public 

入れ子型のための公開のアクセス可能性。 

10.1.1 

| private 

最上位の型の非公開の可視性。 

10.1.1 

| public 

最上位の型の公開の可視性。 

10.1.1 

| rtspecialname 

実行時による特例。 

10.1.6 

| sealed 

型は派生することが可能でない。 

10.1.4 

| sequential 

フィールドの配置は,連続とする。 

10.1.2 

| serializable 

予約(型を直列化することができることを示すため) 

10.1.6 

| specialname 

ツールによる特例が得られてもよい。 

10.1.6 

background image

144 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

| unicode 

Unicodeとしてプラットフォームへ文字列を組み換え
る。 

10.1.5 

10.1.1 可視性及びアクセス可能性の属性 

《クラス属性》 ::= … 
| nested assembly 
| nested famandassem 
| nested family 
| nested famorassem 
| nested private 
| nested public 
| private 
| public 

第1章を参照する。別の型に入れ子にされていない型は,厳密に一つの可視性(private又はpublic)

をもたなければならないし,アクセス可能性があってはならない。入れ子型は,可視性をもってはならな

いが,その代わり,アクセス可能性属性(nested assembly,nested famandassem,nested family,

nested famorassem,nested private又はnested public)を厳密に一つもたなければならない。

最上位の型のための省略時の可視性は,privateとする。入れ子型のための省略時のアクセス可能性は,

nested privateとする。 

10.1.2 型配置属性 

《クラス属性》 ::= … 
| auto 
| explicit 
| sequential 

型配置は,型のインスタンスのフィールドがどのように配置されるかを規定する。与えられた型は,た

だ一つの配置属性を指定されたようにしておかなければならない。便宜上,配置属性が指定されていない

場合,ilasmはautoを供給する。配置属性は,次の三つとする。 

auto:配置は,利用者が指定した制約がないから,CLIによって行われなければならない。 

explicit:フィールドの配置は,明示的に提供される(10.7参照)。しかしながら,総称型は明示的な

配置をもってはならない。 

sequential:CLIは,論理的なメタデータ表の中のフィールドの順序に基づいて,連続する順にフィー

ルドを配置しなければならない(22.15参照)。 

注記 根拠としては,省略時のautoの配置は,コードを実行しているプラットフォームのために最

良の配置を提供したほうがよいことによる。sequentialの配置は,個々のプラットフォーム

上のC及びC++のような言語が一般に従う配置規則に合うようにCLIに命じるように意図され

る。ここで,これは依然として正当性検証可能な配置を保証する間に可能とする。explicit

の配置では,CILジェネレータが正確な配置意味を規定できる。 

10.1.3 型意味属性 

《クラス属性》 ::= … 
| interface 

型意味属性は,インタフェース,クラス又は値型が定義されなければならないかどうかを明示する。イ

ンタフェース属性は,インタフェースを指定する。この属性が存在せず,定義がSystem.ValueTypeを

(直接的又は間接的に)拡張し,System.Enumの定義が存在しない場合,値型が定義されなければなら

ない(箇条13参照)。そうでなければ,クラスが定義されなければならない(箇条11参照)。 

background image

145 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

例 (参考): 

.class interface public abstract auto ansi ʼSystem.IComparableʼ { … } 

インタフェース属性が存在しているため,System.ICompatibleは,インタフェースとする。 

.class public sequential ansi serializable sealed beforefieldinit 

    ʼSystem.Doubleʼ extends System.ValueType implements 

System.IComparable, 

     … { … } 

System.Doubleは,直接的にSystem.ValueTypeを拡張する。System.Doubleは,型

System.Enumではないので,System.Doubleは値型とする。 

.class public abstract auto ansi serializable 

beforefieldinit ʼSystem.Enumʼ 

    extends System.ValueType implements System.IComparable, … { … } 

System.Enumは,System.ValueTypeを直接的に拡張するが,System.Enumは,値型では

ないので,クラスとする。 

.class public auto ansi serializable beforefieldinit ʼSystem.Randomʼ 

    extends System.Object { … } 

System.Randomは,インタフェース又は値型としないため,クラスとする。 

値型の実行時の大きさが1Mバイト(0x100000バイト)を超過してはならないことに注意する。 

10.1.4 継承属性 

《クラス属性》 ::= … 
| abstract 
| sealed 

特殊な意味を指定する属性は,abstract又はsealedとする。これらの属性はともに使用することが

できる。 

abstractは,この型がインスタンス化されてはならないことを指定する。型が抽象メソッドを含んで

いる場合,型は,抽象型として宣言されなければならない。 

sealedは,型は派生クラスをもってはならないことを指定する。すべての値型は,封印されなければ

ならない。 

注記 根拠としては,封印型の仮想メソッドを上書きすることができないから,それらは,効果的な

インスタンスメソッドとなることによる。それらが利用者の拡張可能性のための便利なビルド

ブロックを供給しないから,フレームワーク作成者は,封印クラスを控え目に使用したほうが

よい。単一のクラス(典型的には複数のインタフェース)の仮想メソッドの集合に対する実装

が相互に依存する場合,又は潜在的な派生クラスに対して可視でない実装詳細に大いに依存す

る場合,封印クラスが必要とされる可能性がある。 

abstract,かつ,sealed である型は,静的メンバだけをもつのが望ましく,言語によっ

ては“名前空間”又は“静的クラス”と呼ばれるものとして供給される。 

10.1.5 相互運用属性 

《クラス属性》 ::= … 
| ansi 
| autochar 
| unicode 

background image

146 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

これらの属性は,管理外コードとの相互運用向けとする。それらは,それらを指定したクラス上の

System.Stringの実引数又は返却値の型をもち,それ自体を組み換える振る舞いを指定しない(静的,

インスタンス,又は仮想)メソッドを呼び出す場合に使用される省略時の動作を指定する。型に対して一

つの値だけが指定されていなければならない。また,省略時の値はansiとする。相互運用属性は次の三

つとする。 

ansiは,組換えがANSIの文字列間でなければならないことを指定する。 

autocharは,CLIが実行中のプラットフォーム上に依存した組み換えする振る舞いを指定する(ANSI

又はUnicodeのいずれかになる。)。 

unicodeは,組換えがUnicode 文字列間でなければならないことを指定する。 

これら三つの属性に加えて,23.1.15は,追加のビットパターン(CustomFormatClass及び

CustomStringFormatMask)を規定する。これらは標準化された意味をもたない。これらのビットが設

定されているが,実装がこれらを提供しない場合,System.NotSupportedExceptionが送出される。 

10.1.6 特殊扱い属性 

《クラス属性》 ::= … 
| beforefieldinit 
| rtspecialname 
| serializable 
| specialname 

これらの属性は,任意の方法で組み合せることができる。 

beforefieldinitは,静的メソッドが呼び出される前に,CLIが型を初期化する必要はないことを

CLIに教える(10.5.3参照)。 

rtspecialnameは,この項目の名前がCLIに対して特殊な重要性をもっていることを示す。現在定義

された特殊な型名は,ない。これは,将来使用される。rtspecialnameと印付けられたどんな項目も,

specialnameと印付けられなければならない。 

serializableは,将来の使用のため予約される。serializableは,型のフィールドがデータ流れ

に直列化されることを示す。(実装によってこのような提供が供給されることが望ましい。)。 

specialnameは,この項目の名前がCLI以外のツールに対して特殊な重要性をもっているかもしれな

いことを示す(第1章参照)。 

注記 根拠としては,項目がCLIによって特別に扱われる場合,ツールもそれを知っているようにな

ったほうがよいことによる。逆は,真ではない。 

10.1.7 総称仮引数群(《総称仮引数群》) 

総称型を定義する場合,総称仮引数が含まれる。 

《総称仮引数群》::= 

《総称仮引数》 [ ',' 《総称仮引数群》 ] 

非終端の《総称仮引数》は,次の生成規則をもつ 

《総称仮引数》::= 

  [ 《総称仮引数属性群》 ]*  [  '(' [ 《総称制約群》 ] ')'  ] 《識別子》 

《総称仮引数属性群》::= 

  ʻ+ʼ 

| ʻ-ʼ 

| class 

background image

147 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

| valuetype 

| .ctor 

+は,共変総称仮引数(9.5参照)を意味する。 

-は,反変総称仮引数(9.5参照)を意味する。 

classは,《識別子》を参照型とするための特別な目的の制約とする。 

注記 これは,クラス又は基底型制約を通じて参照型となる制約を型仮引数自身に制約することを含

む。 

valuetypeは,《識別子》を値型とするための特別な目的の制約とする。ただし,その型は,

System.Nullable<T>であってはならないし,また,System.Nullable<T>の具象の閉型のどれかで

あってはならない。 

注記 これは,自身が値型に制約される型仮引数を含む。 

.ctorは,《識別子》を引数のない公開構築子(省略時構築子)をもつ具象な参照(すなわち仮想では

ない)型とする又は値型とするための特別な目的の制約とする。 

注記 これは,自身が具象参照型又は値型に制約される型仮引数を含む。 

class及びvaluetypeは,同一の《識別子》へ同時に指定してはならない。 

例 

.class C< + class .ctor (class System.IComparable<!0>) T > { … } 

これは,名前Tの共変総称仮引数をもつ総称クラスC<T>を宣言する。Tは,

System.ICompatible<T>を実装しなければならないと制約される。また,公開省略時構築子

をもつ具象クラスとしなければならない。 

最後に,非終端な《総称制約群》は,次の生成規則をもつ。 

《総称制約群》 ::= 

《型》[ ',' 《総称制約群》 ] 

《総称制約群》の生成規則内の《識別子》は重複してはならない。 

例 インタフェースI1,インタフェースI2及びクラスBaseの適切な定義を仮定して,次のコード

は,二つの総称仮引数K及び総称仮引数VをもつクラスDictを定義する。この場合Kは,イン

タフェースI1及びI2の両方を実装し,Vは,クラスBaseからの派生と制約される。 

.class Dict̀2<(I1,I2)K, (Base)V> { … } 

次の表は,型及び型の代表集合のための特別な制約の妥当な組合せを示す。第1列の集合(型制約 

System.Object)は,基底クラスの制約が指定されていない場合,又は,基底クラスの制約が

System.Objectである場合のいずれ一方を適用する。記号

は,“設定”を意味し,記号

は,“非設定”

を意味し,記号*は,“設定又は非設定のいずれか”すなわち,“気にしない”ことを意味する。 

型制約 

特別な制約 

意味 

class 

valuetype 

.ctor 

(System.Object) 

任意の型 

任意の参照型 

省略時構築子をもつ任意の参照型 

System.Nullable<T>を除く任意の値型 

公開省略時構築子を伴う任意の型 

不当 

System.ValueType 

System.Nullable<T>を含む任意の値型 

System.Nullable<T>を除く任意の値型 

background image

148 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

任意の値型,System.ValueType及び
System.Enum 

System.ValueType及びSystem.Enumだ
け 

意味がない:インスタンス化できない
(System.ValueTypeから派生できる参照
型がインスタンス化できない。) 

不当 

System.Enum 

任意のenum型 

任意のenum型及びSystem.Enum 

System.Enumだけ 

意味がない:インスタンス化できない
(System.Enumから派生できる参照型がイ
ンスタンス化できない。) 

不当 

System.INullableValue 

任意のSystem.Nullable<t>,又はインタ
フェースを実装する他の型 

任意のSystem.Nullable<t>,又は省略時
構築子を伴うインタフェースを実装する他
の型 

System.INullableValueを実装する任意
の参照型(ただし,System.Nullable<T>
は含まれないことに注意する。) 

System.INullableValueを実装する任意
の参照型(ただし,System.Nullable<T>
は含まれないことに注意する。) 

System.INullableValueを実装する任意
の値型(ただし,System.Nullable<T>は
含むことに注意する。) 

不当 

System.Exception(任意の
特別ではない参照型の例) 

System.Exception

System.Exceptionから派生する任意のク
ラス 

公開の省略時構築子をともなう任意の
System.Exception 

System.Exception

Systen.Exceptionから派生する任意のク
ラス。これは,クラス制約が指定されていな
いときと全く同一の結果になる。 

公開の省略時構築子をともなう任意の例外 

意味がない:インスタンス化できない(値型
は参照型から派生できない。) 

不当 

System.Delegate 

System.Delegate

System.Delegateから派生される任意の
クラス 

意味がない:インスタンス化できない(省略
時構築子がない。) 

System.Delegate

background image

149 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

System.Delegateから派生される任意の
クラス 

任意の公開な.ctorを伴う代理。既知の代理
(System.Delegate)は不当 

意味がない:インスタンス化できない(値型
は,参照型から派生できない。) 

不当 

System.Array 

任意の配列 

意味がない:インスタンス化できない(省略
時構築子がない。) 

任意の配列 

意味がない:インスタンス化できない(値型
は参照型から派生できない。) 

不当 

例 次のインスタンス化は,制約に基づき許可又は許可されない。これらのインスタンスのすべてに

おいて,宣言自体は許可される。Invalidと印づけられた項目は,指定された型をインスタンス

化しようと試みた場合に正当性検証に失敗することを示す一方,Validと印づけられた項目は,

そうではない。 

.class public auto ansi beforefieldinit Bar̀1<valuetype T> 

Valid 

ldtoken 

class Bar̀1<int32> 

Invalid ldtoken 

class Bar̀1<class 

[mscorlib]System.Exception> 

Invalid ldtoken 

class Bar̀1<Nullablè1<int32>> 

Invalid ldtoken 

class Bar̀1<class [

mscorlib]System.ValueType> 

.class public auto ansi beforefieldinit 'Bar̀1'<class T> 

Invalid ldtoken 

class Bar̀1<int32> 

Valid 

ldtoken 

class Bar̀1<class 

[mscorlib]System.Exception> 

Invalid ldtoken 

class Bar̀1<valuetype 

[mscorlib]System.Nullablè1<int32>> 

Valid 

ldtoken 

class Bar̀1<class 

[mscorlib]System.ValueType> 

.class public auto ansi beforefieldinit Bar̀1<(class 

[mscorlib]System.ValueType) T> 

Valid 

ldtoken 

class Bar̀1<int32> 

Invalid ldtoken 

class Bar̀1<class 

[mscorlib]System.Exception> 

Valid 

ldtoken 

class Bar̀1<valuetype  

[mscorlib]System.Nullablè1<int32>> 

Valid 

ldtoken 

class Bar̀1<class 

[mscorlib]System.ValueType> 

.class public auto ansi beforefieldinit Bar̀1<class (int32)> T> 

background image

150 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

Invalid ldtoken 

class Bar̀1<int32> 

Invalid ldtoken 

class Bar̀1<class 

[mscorlib]System.Exception> 

Invalid ldtoken 

class Bar̀1<valuetype  

[mscorlib]System.Nullablè1<int32>> 

Invalid ldtoken 

class Bar̀1<class 

[mscorlib]System.ValueType> 

注記 この型は,int32を拡張することができる参照型がないときには,インスタンス化す

ることはできない。 

.class public auto ansi beforefieldinit Bar̀1<valuetype 

(class [mscorlib]System.Exception)> T> 

Invalid ldtoken 

class Bar̀1<int32> 

Invalid ldtoken 

class Bar̀1<class 

[mscorlib]System.Exception> 

Invalid ldtoken 

class Bar̀1<valuetype  

[mscorlib]System.Nullablè1<int32>>  

Invalid ldtoken 

class Bar̀1<class 

[mscorlib]System.ValueType>  

注記 この型は,System.Exceptionを拡張することができる値型がないときには,イン

スタンス化することはできない。 

.class public auto ansi beforefieldinit Bar̀1<.ctor (class Foo) T> 

この場合,Fooは,公開な.ctorはもたないがFooBarをもつ,FooBarはFooから派生し,

公開な.ctorをもつ。 

Invalid ldtoken 

class Bar̀1<class Foo> 

Valid 

ldtoken 

class Bar̀1<class FooBar> 

10.2 型定義の本体 

型は,さらなる宣言を幾つでも含むことができる。指令.event,指令.field,指令.method及び指

令.propertyは,型のメンバを宣言するために使用する。型宣言の内部の指令.classは,入れ子型を生

成するために使用される。さらなる詳細は,10.6で検討する。 

《クラスメンバ》 ::= 

記述 

箇条又は 
細分箇条 

  .class 《クラスヘッダ》 ʻ{ʼ 《クラスメンバ》* ʻ}ʼ 入れ子型を定義する。 

10.6 

| .custom 《カスタム宣言》 

カスタム属性。 

21 

| .data 《データ宣言》 

型に関連した静的データを
定義する。 

16.3 

| .event 《イベントヘッダ》ʻ{ʼ 《イベントメンバ》* 
ʻ}ʼ 

イベントを宣言する。 

18 

| .field 《フィールド宣言》 

型に属するフィールドを宣
言する。 

16 

| .method 《メソッドヘッダ》 ʻ{ʼ 《メソッド本体項
目》* ʻ}ʼ 

型のメソッドを宣言する。 15 

| .override 《型指定》 ʻ::ʼ 《メソッド名》 with 《呼

最初のメソッドが2番目の

10.3.2 

background image

151 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

出し規約》 《型》 《型指定》 ʻ::ʼ 《メソッド名》 ʻ(ʼ 
《仮引数群》 ʻ)ʼ 

メソッドの定義によって上
書きされることを指定す
る。 

| .pack 《Int32》 

フィールドの明示的な配置
に使用される。 

10.7 

| .param type ʻ[ʼ 《Int32》ʻ]ʼ 

総称型の型仮引数を指定す
る。すなわち,あるカスタ
ム属性をその型仮引数に関
連付けるときに用いる。 

15.4.1.5 

| .property 《特性ヘッダ》 ʻ{ʼ 《特性メンバ》* ʻ}ʼ 型の特性を宣言する。 

17 

| .size 《Int32》 

フィールドの明示的な配置
に使用される。 

10.7 

| 《外部ソース宣言》 

ソース行情報 

5.7 

| 《セキュリティ宣言》 

セキュリティ許可宣言 

20 

10.3 仮想メソッドの導入及び上書き 

基底型の仮想メソッドは,メソッドの直接の実装を(メソッド定義を用いて,15.4参照)提供し,それ

をnewslot(15.4.2.3参照)とすると指定しないことによって上書きされる。既存のメソッド本体も指

令.override(10.3.2参照)を用いて,与えられた仮想宣言を実装するために使用することができる。 

10.3.1 仮想メソッドの導入 

仮想メソッドは,仮想メソッド(15.4参照)の定義によって継承階層構造において導入される。その定

義には,定義するクラス及びそれから派生する任意のクラスのための新しい仮想メソッドを常に生成する

ためにnewslotと印づけることができる。 

− 定義がnewslotと印付けられている場合,基底クラスが条件に合う仮想メソッドを提供しても,そ

の定義は,常に新しい仮想メソッドを生成する。メソッド定義を含むクラス又はそのクラスから派生

したクラスを経由した仮想メソッドへの参照は,(派生クラス内のnewslot定義によって隠ぺいされ

ていない限りにおいて)新しい定義を参照する。メソッド定義を含むクラス又はその派生クラスを経

由しない仮想メソッドへの任意の参照は,原型の定義を参照する。 

− 定義がnewslotと印付けられていない場合,基底クラスから継承した同じ名前及び同じ識別情報の

仮想メソッドがない場合だけ,それは,新しい仮想メソッドを生成する。 

仮想メソッドがnewslotと印づけられている場合,その導入は,基底クラス内の一致する仮想メソッ

ドへの,どの既存の参照に影響を与えない。 

10.3.2 .override指令  

指令.overrideは,仮想メソッドが,この型の中で,異なる名前だが同じ識別情報を備えた仮想メソ

ッドによって実装されなければならない(上書きされなければならない)ことを指定する。この指令は,

基底クラスから継承した仮想メソッド又はこの型によって実装されたインタフェースで指定された仮想メ

ソッドに実装を供給するために使用することができる。指令.overrideは,メタデータ中でメソッド実

装(MethodImpl)を指定する(15.1.4参照)。 

《クラスメンバ》 ::= 

箇条 

  .override 《型指定》 ʻ::ʼ 《メソッド名》 with 《呼出し規約》 《型》 《型指定》 ʻ::ʼ 
《メソッド名》 ʻ(ʼ 《仮引数群》 ʻ)ʼ 

.override method 《呼出し規約》 《型》《型指定》 ʻ::ʼ 《メソッド名》《総称仮引数数》 
( 《仮引数群》 ) with method 《呼出し規約》 《型》 《型指定》 ʻ::ʼ 《メソッド名》《総
称仮引数数》 ʻ(ʼ 《仮引数群》 ʻ)ʼ 

| … 

10.2 

background image

152 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

《総称仮引数数》 ::= [ ʻ<ʼ ʻ[ʻ 《Int32》 ʻ]ʼ ʻ>ʼ ] 

《Int32》は,総称仮引数の個数とする。 

最初の《型指定》::《メソッド名》対は,上書きされている仮想メソッドを指定し,継承した仮想メソ

ッド又は現在の型が実装するインタフェースの仮想メソッドのいずれかでなければならない。残りの情報

は,実装を提供する仮想メソッドを指定する。 

ここに規定された構文も実際のメタデータの書式(22.27参照)も,実装を提供するために任意の仮想メ

ソッドが使用されることを可能にする一方で,適合プログラムは,指令.overrideを含んでいる型で実

際に直に実装された仮想メソッドを提供しなければならない 

注記 根拠としては,メタデータは,VESのすべての実装が期待するよりも,より多くのことが表現

できるように設計されていることによる。 

例  

次の例は,指令.overrideの典型的な使用を示す。メソッド実装は,インタフェースで宣言され

たメソッドに対して供給される(箇条12参照)。 

.class interface I 

{ .method public virtual abstract void M() cil managed {} 

.class C implements I 

{ .method virtual public void M2() 

  { // M2の本体 

  } 

  .override I::M with instance void C::M2() 

指令.overrideは,C::M2本体はクラスCのオブジェクト上のI::Mを実装するために使用

されるという実装を提供しなければならないことを指定する。 

10.3.3 アクセス可能性及び上書き 

strictフラグ(23.1.10参照)が指定された場合,アクセス可能な仮想メソッドだけが上書きできる。 

型が,MethodImple以外の方法を通じて継承されたメソッドを上書きする場合,そのメソッドのアク

セス可能性を拡大することができる。しかし,それを縮小してはならない。原理的には,型のクライアン

トがその型のメソッドをアクセスすることを許される場合,それは,更に,任意の派生型中で(名前及び

識別情報によって識別された)メソッドをアクセスすることができなければならない。表1は,この文脈

における縮小及び拡大を規定する。“はい”は,派生クラスがアクセス可能性を適用することができること

を表す。“いいえ”は,それを不正とすることを表す。 

型がMethodImplを通じて継承されたメソッドを上書きする場合,そのメソッドのアクセス可能性は,

拡大も縮小もできる。 

表1−仮想メソッドへのアクセスの適切な拡大 

派生クラス 

基底型アクセス可能性 

Compiler- 
controlled 

private 

family 

assembly 

famandassem famorassem 

public 

background image

153 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

Compiler- 
controlled 

注3 

いいえ 

いいえ 

いいえ 

いいえ 

いいえ 

いいえ 

private 

注3 

はい 

いいえ 

いいえ 

いいえ 

いいえ 

いいえ 

family 

注3 

はい 

はい 

いいえ 

はい 

注1 

いいえ 

assembly 

注3 

はい 

いいえ 

注2 

注2 

いいえ 

いいえ 

famandassem 注3 

はい 

いいえ 

いいえ 

注2 

いいえ 

いいえ 

famorassem 

注3 

はい 

はい 

注2 

はい 

はい 

いいえ 

public 

注3 

はい 

はい 

はい 

はい 

はい 

はい 

注1 異なるアセンブリの中に両方提供されるならば,はい。そうでなければ,いいえ。 
注2 同一のアセンブリの中に両方提供されるならば,はい。そうでなければ,いいえ。 
注3 同一のモジュールの中に両方提供されるならば,はい。そうでなければ,いいえ。 

注記 メソッドが派生クラスによってアクセスされないかもしれなくても,メソッドは,上書きする

ことができる。 

メソッドがアセンブリ(assembly)アクセス可能性をもっているとき,それが異なるアセ

ンブリでのメソッドによって上書きされている場合,それは公開(public)のアクセス可能

性をもたなければならない。同様の規則はfamandassemアクセス可能性をもっている場合に

も適用され,更に,アセンブリの外部で上書きするメソッドがfamorassemアクセス可能性を

もつことも許可される。両方の場合において,同じアセンブリの内部では,それぞれアセンブ

リ(assembly)又はfamandassemアクセス可能性を使用することができる 

表1の中で示されるように,特殊な規則は,famorassemに適用する。これは,アクセス可能性が下位

クラスによって見かけ上縮小される唯一のケースとする。famorassemメソッドは,別のアセンブリでの

型によってfamilyのアクセス可能性で上書きされてもよい。 

注記 根拠としては,“ファミリ又は特殊な他のアセンブリ”を指定する方法がないから,アクセス可

能性を不変としなければならないことを指定することができないことによる。アクセスを縮小

することを回避するために,それが望まれない場合さえアクセスの拡大を強制することになる

publicのアクセス可能性を指定することが必要だろう。妥協として,“ファミリ”だけの小さな

縮小は,許可される。 

10.4 メソッド実装要件 

型(具象又は仮想)は,次の四つの実装要件を提供できる。 

− その型が導入するインスタンスメソッド,静的メソッド及び仮想メソッドに対する実装。 

− その型で実装されると指定されているインタフェース又はその基底型で実装されると指定されている

インタフェースで宣言されたメソッドに対する実装。 

− その基底クラスから継承した仮想メソッドのための代替の実装。 

− 実装を提供しなかった抽象基底型から継承した仮想メソッドに対する実装。 

具象(すなわち,抽象ではない)型は,直接的又は次の三つのメソッドに対する実装を継承することに

よって提供しなければならない。 

− その型自体によって宣言されたすべてのメソッド。 

− その型によって実装されたインタフェースのすべての仮想メソッド。 

− その型がその基底型から継承するすべての仮想メソッド。 

10.5 特殊なメンバ 

三つの特殊なメンバがある。それらはすべてメソッドで型の一部として定義することができるメソッド

154 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

であり,インスタンス構築子,インスタンス終了化子及び型初期化子の三つとする。 

10.5.1 インスタンス構築子 

インスタンス構築子は,型のインスタンスを初期化する。型のインスタンスが命令newobj(第3章参照)

によって生成される場合,インスタンス構築子が呼び出される。インスタンス構築子は,インスタンス(静

的でない又は仮想)メソッドでなければならず,それは.ctorと命名されなければならない。また,

instance,rtspecialname及びspecialname(15.4.2.6参照)を印付けたものとする。インスタンス

構築子は,仮引数をもつことができるが,値を返却してはならない。インスタンス構築子は,総称型仮引

数をとることはできない。インスタンス構築子は,多重定義できる。(すなわち,型は,幾つかのインスタ

ンス構築子をもつことができる。)。型に対するインスタンス構築子は,それぞれ一意な識別情報をもたな

ければならない。他のメソッドと異なり,インスタンス構築子は,属性initonly(16.1.2参照)によっ

て印付けられる型のフィールドに書き込むことができる。 

例 

次に,どんな仮引数もとらないインスタンス構築子の定義を示す。 

.class X { 

.method public rtspecialname specialname instance void .ctor() cil 

managed 

  { .maxstack 1 

  //上位の構築子の呼出し 

  ldarg.0  

//this ポインタをロードする。 

  call instance void [mscorlib]System.Object::.ctor() 

  //他の初期化作業をする。 

  ret 

  } 

10.5.2 インスタンス終了化子 

終了化子の振る舞いは,第1章で規定される。特定の型のための終了化メソッドは,System.Object

中の仮想メソッドFinalizeの上書きによって指定される。 

10.5.3 型初期化子 

型(クラス,インタフェース又は値型)は,型自体を初期化するために使用される型初期化子と呼ばれ

る特殊なメソッドを一つ含むことができる。 

このメソッドは,静的でなければならず,仮引数をとってはならず,値を返却してはならず,

rtspecialname及びspecialname(15.4.2.6参照)で印をつけられなければならず,.cctorと命名さ

れなければならない。 

インスタンス構築子のように,型初期化子は,属性initonly(16.1.2参照)で印をつけられるそれら

の型の静的フィールドに書き込むことができる。 

例 次に型初期化子の定義を示す。 

.class public EngineeringData extends [mscorlib]System.Object 

.field private static initonly float64[] coefficient 

.method private specialname rtspecialname static void .cctor() cil 

155 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

managed 

  { 

  .maxstack 1 

  // allocate array of 4 Double 

  ldc.i4.4 

  newarr     [mscorlib]System.Double 

  // point initonly field to new array 

  stsfld     float64[] EngineeringData::coefficient 

  // code to initialize array elements goes here 

  ret 

  } 

注記 型初期化子は,多くの場合,格納された定数から又は単純な計算によって,型の静的フィール

ドを初期化するといった単純メソッドである。しかし,型初期化子の中ではどのようなコード

も許可されている。 

10.5.3.1 型初期化保証 

CLIは,型初期化に関する次の保証を提供しなければならない(10.5.3.2及び10.5.3.3参照)。 

1) 型初期化子がいつ実行されるかに関しては,第1章で規定される。 

2) 型初期化子は,利用者コードによって明示的に呼び出されない限り,与えられたどんな型に対して

も正確に一度で実行しなければならない。 

3) その初期化子が実行を終える前に,型初期化子から直接的又は間接的に呼び出される側以外のメソ

ッドは,型のメンバをアクセスすることができない。 

10.5.3.2 緩和された保証 

型は,10.5.3.1で規定されたすべての保証が必要だとは限らないことを示すために,属性

beforefieldinit(10.1.6参照)と印付けることができる。特に,10.5.3.1の最後の要件を提供する必要

はない。すなわち,型初期化子は,静的メソッドが呼び出される又は参照される前に実行する必要はない。 

注記 根拠としては,多重アプリケーション領域中でコードを実行することができる場合,この最後

の保証を保証することは特にコストがかかるようになることによる。同時に,型初期化子は,

ほとんどの場合,静的フィールドを初期化する単純なメソッドなので,管理下コードの大きな

本体の検査は,この最後の保証がめったに必要でないことを示している。したがって,それが

一貫性保証のコストを犠牲にして望まれる場合,CILジェネレータに(したがって,おそらく

プログラマに)この保証が必要かどうか決定することが任されていることは,効率を提供する。 

10.5.3.3 競合及びデッドロック 

10.5.3.1で規定された型初期化保証に加えて,CLIは,型初期化子から呼び出される側のコードの二つの

さらなる保証を確保しなければならない。 

1) 型の静的変数は,あらゆる任意のアクセスに先立って既知の状態とする。 

2) (直接的又は間接的に)明示的なブロック操作の呼出しを行う型初期化子からあるコードが呼び出

されない限り,型初期化単独では,デッドロックを生成してはならない。 

注記 根拠として,次の二つのクラス定義を考える。 

.class public A extends [mscorlib]System.Object 

156 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

{ .field static public class A a 

  .field static public class B b 

  .method public static rtspecialname specialname void .cctor () 

  { ldnull  

// b=null 

    stsfld class B A::b 

    ldsfld class A B::a // a=B.a 

    stsfld class A A::a 

    ret 

  } 

.class public B extends [mscorlib]System.Object 

{ .field static public class A a 

  .field static public class B b 

  .method public static rtspecialname specialname void .cctor () 

  { ldnull  

// a=null 

    stsfld class A B::a 

    ldsfld class B A::b // b=A.b 

    stsfld class B B::b 

    ret 

  } 

これらの二つのクラスをロードした後に,A及びB各々の型初期化子が,他方の型初期化子

が最初に呼び出されることを必要とするから,静的フィールドのうちのいずれかを参照する試

みは,問題を引き起こすことによる。その初期化子が完了するまで型へのアクセスがアクセス

を許可しないことを要求することは,デッドロック状況を作るだろう。代わりに,CLIは,初

期化子は実行を開始するが,それは完了する必要はないという,より弱い保証を提供する。し

かし,これは,単独で完全に初期化されていない型の状態が可視とすることを可能にするだろ

う。それは,再現性のある結果を保証することを困難にするだろう。 

型初期化が多重スレッド化されたシステムで起こる場合,そこには,類似しているがより複

雑な問題がある。これらの場合,例えば,二つの別個のスレッドが,個別の型(A及びB)の

静的変数をアクセスすることを試み始めると,各々は,初期化を完了するために他方を待機し

なければならないだろう。 

上記の点1及び点2を保証するアルゴリズムの荒い概略は,次のとおりとする。 

1. クラス読込み時(したがって,初期化時に先立つ)に,型のすべての静的フィールドにゼロ

又はナルを格納する。 

2. 型が初期化される場合,終了する。 

2.1. 型がまだ初期化されない場合は,初期化のロックをとろうとする。 

background image

157 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

2.2. 成功した場合,型の初期化に責任を負うものとしてこのスレッドを記録し,手順2.3に進

む。 

2.2.1. 成功しなければ,このスレッド,又はこのスレッドが完了するのを待っている他のスレ

ッドが,既にロックを保持しているかどうか確かめる。 

2.2.2. そうならば,デッドロックを生成するから戻る。このスレッドは,現時点で,型のため

の不完全に初期化された状態であるが,デッドロックは発生しない。 

2.2.3 そうでなければ,型が初期化されるまでブロックを行った後,戻る。 

2.3基底クラス型を初期化する。そして,この型によって実装されたすべてのインタフェースを

初期化する。 

2.4 この型のための型初期化コードを実行する。 

2.5 型に初期化済みの印をつけ,初期化ロックを解放し,この型が初期化されるのを待ってい

る他のスレッドを起こし,そして,戻る。 

10.6 入れ子型 

入れ子型は,第1章で規定される。入れ子型に関連した論理的な表に関する情報については,22.32を参

照する。 

注記 入れ子型は,その取囲み型のインスタンスに関係していない。入れ子型は,それ自身の基底型

をもっており,取囲み型と無関係にインスタンス化されていてもよい。これは,取囲み型のイ

ンスタンスメンバが入れ子型のthis ポインタを用いてアクセス可能ではないことを意味する。 

入れ子型は,その取囲み型のメンバが静的な場合,又は入れ子型がその取囲み型のインスタ

ンスへの参照をもつ場合には,非公開メンバを含み,その取囲み型のどんなメンバであっても

アクセスすることができる。したがって,入れ子型の使用によって,型は,別の型にその非公

開メンバへのアクセス権を与えることができる。 

他方,取囲み型は,任意の入れ子型の非公開又はファミリメンバへアクセスできない。

assembly,famorassem又はpublicのアクセス可能性を備えたメンバだけは,取囲み型に

よってアクセスすることができる。 

例 

次の例は,クラスを別のクラスの内側に宣言したことを示す。各々のクラスは,フィールドを

宣言する。入れ子クラスは,両方のフィールドをアクセスすることができる。一方,取囲みクラ

スは,囲まれたクラスのフィールドbにアクセスできない。 

.class public auto ansi X 

{ .field static private int32 a 

  .class auto ansi nested public Y  

  { .field static private int32 b 

    // ... 

  } 

10.7 インスタンスの配置制御 

CLIは,連続的な配置制御及び明示的な配置制御の両方を行う(10.1.2参照)。明示的な配置では,イン

スタンスの正確な配置をも指定しなければならない(22.18及び22.16参照)。 

《フィールド宣言》 ::= 
[ʻ[ʼ 《Int32》 ʻ]ʼ] 《フィールド属性》* 《型》 《識別子》 

158 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

宣言の初めの角括弧([])の中で指定された省略可能な《Int32》は,型のインスタンスの先頭位置か

らのバイトオフセットを指定する。(与えられた型tに対して,この先頭位置は,型tにおいて明示的に定

義されるメンバの集合の先頭を参照するが,型tから直接的又は間接的に継承する任意の型において定義

されるすべてのメンバを除外する。)この明示的な配置制御の形式は,at記法(16.3.2参照)を用いて指

定された大域フィールドに用いてはならない。 

オフセット値は,負数以外でなければならない。たとえ,オブジェクト参照によって占有されたオフセ

ットが,組込みの値型又は別のオブジェクト参照の一部によって占有されたオフセットにオーバラップし

てはいけないとしても,このようにフィールドをオーバラップさせることは可能とする。あるオブジェク

ト参照が完全に別なオブジェクト参照をオーバラップすることができる一方,これは,正当性検証可能で

はないとする。 

フィールドは,ポインタ演算及び,フィールドを間接的にロードするためのldind,又は,フィールド

を間接的に格納するためのstindを用いてアクセスすることができる(第3章参照)。この情報の符号化

については22.16及び22.18を参照。明示的な配置については,すべてのフィールドは,オフセットを割

り当てられなければならない。 

指令.packは,実行時オブジェクト内にフィールドを置くときのアドレスについて指令する。そのアド

レスは,指定された数値の倍数と,そのフィールドの型のための自然な境界調整との二つの小さい方とす

る。例えば,.pack 2は,幅32ビットのフィールドが偶数アドレス上で始まることを許される。指令.pack

なしでは,それらは自然な境界に調整されるだろう。すなわち,4の倍数とするアドレスに置かれる。.pack

に続く整数は,0,1,2,4,8,16,32,64又は128のいずれか一つでなければならない(ゼロ値は,使

用されるパックの大きさが現プラットフォームのための省略時と合わなければならないことを示す。)。指

令.packに明示的な配置制御がついたどんな型の供給もされてはならない。 

指令.sizeは,最小サイズを示し,埋込みを許可することを意図する。すなわち,メモリが割り付けら

れた量は,その配置及び指令.sizeから算出された最大サイズとする。この指令を値型に適用する場合,

大きさが1Mバイト未満としなければならないことに注意する。 

注記 インスタンス配置を制御するメタデータは,“ヒント”ではない。すべての CLI規格適合処理系

が採用しなければならないVESの不可欠な部分とする。 

例 次のクラスは,そのフィールドの連続的な配置を使用する。 

.class sequential public SequentialClass 

{ .field public int32 a  

// オフセット0バイトの格納 

  .field public int32 b  

// オフセット4バイトの格納 

次のクラスは,そのフィールドの明示的な配置を使用する。 

.class explicit public ExplicitClass 

{ .field [0] public int32 a 

// オフセット0バイトの格納 

  .field [6] public int32 b 

// オフセット6バイトの格納 

次の値型は,そのフィールドをパックするために.packを使用する。 

.class value sealed public MyClass extends [mscorlib]System.ValueType 

{ .pack 2 

  .field  public int8  a   

// オフセット0バイトの格納 

159 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

  .field  public int32 b  

// オフセット2バイト(4バイトではない)の格

納 

次のクラスは,16バイトの隣接したブロックを指定する。 

.class public BlobClass 

{ .size 

16 

10.8 大域フィールド及び大域メソッド 

静的メンバを備えた型に加えて,多くの言語が,全く型に属さないデータ及びメソッドという概念をも

つ。これらは,大域フィールド及び大域メソッドと呼ばれる。 

CLIの中の大域フィールド及び大域メソッドを理解する最も単純な方法は,それらを不可視の

abstract公開クラスの単純なメンバと想定することである。実際に,CLIは,基底型をもたず,インタ

フェースを実装しない<Module>という名前の特殊なクラスを定義する。(このクラスは,最上位クラスと

する。すなわち,入れ子ではない。)通常のモジュールとの唯一の違いは,複数のモジュールを組み合わせ

る場合での,この特殊なクラスの定義に対するクラスローダの扱いにある。この処理は,メタデータ併合

として知られる。 

通常の型では,メタデータは,同じ型の二つの定義を併合したならば,それらが同等であること,そし

て,型が使用されるときに何らかの差異が発見されるという仮定の上で,もう一つの定義を破棄する。し

かし,大域メンバを保持する特殊なクラスについては,メンバは,併合時にすべてのモジュールにわたっ

て結合される。同じ名前が複数のモジュールにおいてモジュールをまたがった使用のための定義がなされ

ているように現れる場合,エラーが起こる。次に詳細を示す。 

− 同じ種類(フィールド又はメソッド)のメンバ,同じ名前,及び同じ識別情報が存在しない場合は,

出力クラスにこのメンバを加える。 

− 重複があり,そのうちの一つだけがcompilercontrolled以外のアクセス可能性をもっている場合

は,出力クラスにそれらをすべて加える。 

− 重複があり,そのうちの二つ以上が,compilercontrolled以外のアクセス可能性をもっている場

合,エラーが生じる。 

注記 厳密にいえば,CLIは,たとえ,大域フィールド及び大域メソッドがそのように考えられても

よいとしても,大域で静的であることを提供しない。モジュール内のすべての大域フィールド

及び大域メソッドは,製造時のクラス<Module>によって所有される。しかしながら,各モジ

ュールは,独自のクラス<Module>をもつ。このような別なモジュール内の大域フィールド又

は大域メソッドへの早期束縛や参照ですら,それを行う方法はない(しかしながら,自己反映

によってそれらに到達すること又は後期束縛をすることはできる。)。 

11 クラスの意味 

第1章で規定されるように,クラスは,継承階層構造での型を定義する。(組込みのクラス

System.Object及び特別なクラス<Module>を除いて)クラスは,厳密に一つの基底クラスを宣言しな

ければならない。クラスは,そのクラスが実装するゼロ個以上のインタフェースを宣言しなければならな

い(箇条12参照)。具象クラスは,オブジェクトを生成するためにインスタンス化されてもよい。しかし,

160 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

抽象クラス(10.1.4参照)は,インスタンス化されてはならない。クラスは,フィールド(静的又はイン

スタンス),メソッド(静的,インスタンス又は仮想),イベント,特性及び入れ子型(クラス,値型又は

インタフェース)を定義できる。 

クラスのインスタンス(すなわちオブジェクト)は,命令newobjを明示的に用いてだけ生成される(第

3章参照)。クラスの変数又はフィールドが,その型として(例えば,クラス型の局所変数をとるメソッド

を呼び出すことによって)生成される場合,その初期値は,nullでなければならない。これは,特定クラ

スのインスタンスでないにもかかわらず,すべてのクラス型に対して:=(代入互換)である特殊な値とす

る。 

12 インタフェースの意味 

インタフェースは,第1章で規定されたように,他の型が実装できる契約を各々定義する。インタフェ

ースは,静的フィールド及び静的メソッドをもつことができるが,インスタンスフィールド又はインスタ

ンスメソッドをもってはならない。インタフェースは,それらのメソッドがabstract(第1章及び15.4.2.4

参照)でありさえすれば,仮想メソッドを定義できる。 

注記 根拠としては,インタフェースは,CLIが基底型の多重継承を採用しないのと同じ理由でイン

スタンスフィールドを定義できないことによる。すなわち,データ型の動的読込みがある状態

で,使用されたとき効率的で,使用しないとき費用がかからない既知の実装技術がないことに

よる。対照的に,静的フィールド及び静的メソッドの提供は,インスタンスの配置に影響しな

いから,これらの問題を引き起こさない。 

インタフェースは,任意の型(インタフェース,クラス又は値型)の内部で入れ子にできる。 

12.1 インタフェースの実装 

クラス及び値型は,0個以上のインタフェースを実装しなければならない。インタフェースの実装とは,

クラス又は値型の具象インスタンスが,そのインタフェースで宣言されたすべてのabstract仮想メソッ

ドの実装を供給しなければならないことを暗黙に意味する。インタフェースを実装するために,クラス型

又は値型は,(その型の定義中の属性implementsを用いて,10.1参照)明示的に宣言するか,インタフ

ェースを実装する基底クラスから派生されなければならない。 

注記 抽象クラスは,(インスタンス化できないから)それが実装するインタフェースの仮想メソッド

の実装を提供する必要はない。しかし,それから派生する具象クラスは,その実装を提供しな

ければならない。 

インタフェースのすべてのabstractメソッドに実装を供給しても,型がそのインタフェー

スを実装するには十分ではない。概念的に,これは,abstractメソッドが取り込むよりも多

くの要件をもつ契約をインタフェースが表現できるという事実を表す。実装の視点からは,こ

れによって,明示的に宣言されたインタフェースによってだけ,型の配置が制約できることを

表す。 

インタフェースは,0個以上の他のインタフェースの実装要求を宣言しなければならない。インタフェ

ースAが,別のインタフェースの実装Bを必要とすると宣言する場合,Aは,Bによって要求されるすべ

てのインタフェースの実装を必要とすると暗黙に宣言する。クラス又は値型がAを実装すると宣言する場

合,すべての具象インスタンスは,Aの中で宣言された仮想メソッド及びAが要求するインタフェースす

べての実装を提供しなければならない。 

注記 クラスは,Aによって要求されるインタフェースを実装すると明示的に宣言する必要はない。 

161 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

例 次のクラスは,モジュールCounterの中で定義されたインタフェース

IStartStopEventSourceを実装する。 

.class private auto autochar StartStopButton  

       extends [System.Windows.Forms]System.Windows.Forms.Button 

       implements [.module Counter]IstartStopEventSource 

{ // クラス本体 

12.2 インタフェース上の仮想メソッドの実装 

インタフェースを実装するクラス(12.1参照)は,そのインタフェースによって定義されたabstract

仮想メソッドに実装を供給しなければならない。実装を提供する三つの機構がある。 

− インタフェース中に現れるように,同じ名前及び同じ呼出し情報を用いて,直接的な実装を指定する

こと。 

− 基底型からの既存の実装の継承。 

− 明示的なMethodImpl(15.1.4参照)の使用。 

仮想実行システムは,インタフェースの仮想抽象メソッドの適切な実装を決定するために次のアルゴリ

ズムを用いる。 

− 基底クラスがインタフェースを実装する場合は,それが提供するのと同じ仮想メソッドで始め,そう

でなければ,すべての仮想関数用の空のスロットをもっているインタフェースを作る。 

− このクラスが,明示的にインタフェース[すなわち,このクラスのInterfaceImpl表(22.23参照)に現

れるインタフェース]を実装することを指定する場合であって, 

− そのクラスが,インタフェース上の仮想メソッドに一致する名前及び識別情報をもつ,あらゆる

public virtual newslotメソッドを定義する場合は,対応するインタフェースメソッドを実装

するために,これらの新しい仮想メソッドを使用する。 

− まだ空のスロットをもっているインタフェースに何らかの仮想メソッドがある場合,このクラス上(直

接的又は継承されて)で同じ名前及び同じ識別情報をもったpublic virtual newslotメソッド

でないpublic virtualメソッドが使用可能かどうかを確認し,インタフェース上の対応するメソ

ッドを実装するためにこれらを使用する。 

− このクラスのために指定されたすべてのMethodImplを適用しなければならない。したがって,名前

一致によって継承している又は選ばれているものより優先して,明示的に指定された仮想メソッドを

そのインタフェースの中に置かなくてはならない。 

− 現クラスがabstractでなく,まだ空のスロットをもっているインタフェースメソッドが存在する場

合,プログラムは不当とする。 

注記 根拠としては,インタフェースは,主に,そのインタフェースを実装するどんなクラスでも実

装されなければならない仮想メソッドの集合を指定することとして考えることができることに

よる。クラスは,それ自身の仮想メソッドからインタフェースの仮想メソッドへの対応付けを

指定する。したがって,それは,仮想メソッドとし,インタフェースに関係するメソッドの特

殊な実装ではないとする。特殊な実装を備えたクラス上の仮想メソッドの上書きは,そのクラ

スで名付けられた仮想メソッドだけでなく,その同じ仮想メソッドが対応付けられたあらゆる

インタフェースの仮想メソッドにも,このように作用する。 

162 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

13 値型の意味 

参照型とは対照的に,値型(第1章参照)は,参照を使ってアクセスされず,その型の格納域に直接的

に格納される。 

注記 根拠としては,値型は,小さなデータ項目の型について記述するために使用されることによる。

それらは,C++ における(構造体へのポインタに対立するものとしての)構造体の型と比較す

ることができる。参照型と比較して,追加の間接参照が含まれないから値型はより速くアクセ

スされる。配列の要素として,それらは,データ自身用に加えてポインタ用のメモリを割り付

けることを要求しない。典型的な値型は,複素数,幾何学的な頂点及び日付とする。 

他の型のように,値型は,(静的又はインスタンス)フィールド,(静的,インスタンス又は仮想)メソ

ッド,特性,イベント及び入れ子型をもつことができる。何らかの値型をもつ値は,ボックス化を呼び出

す処理によって対応する参照型(そのボックス化形式,すなわち,値型が定義されるとき,VESによって

この目的のために自動的に生成されたクラス)のインスタンスに変換されるときがある。ボックス化され

た値型は,ボックス化解除を呼び出す処理によって,その値型表現(ボックス化解除形式)に変換し戻さ

れることがある。値型は,封印されなければならない。また,それらは,System.ValueType又は

System.Enum(第4章参照)のいずれかの基底型をもたなければならない。値型は,ゼロ個以上のイン

タフェースを実装しなければならない。しかし,これは,それらのボックス化形式(13.3参照)の中でだ

け意味をもつ。 

ボックス化解除された値型は,別の型の下位型とは考えられない。また,ボックス化解除された値型に

命令isinst(第3章参照)を使用することは妥当ではない。命令isinstは,ボックス化された値型に使用

されてもよい。ボックス化解除された値型は,値nullを割り当てられてはならない。また,それらはnull

と比較されてはならない。 

値型は,参照型が採用している方法と同じ配置の制御方法を採用する(10.7参照)。値がプラットフォー

ム固有コードから移入される場合,これは特に重要となる。 

値型は,データの直接的配置を表現するため,(C#の構文で書いた場合の)struct S {S x; S y;} の

ような再帰的な構造体定義は許されない。構造体は,非循環で有限の平たんなグラフをもたなければなら

ない。 

値型Sについて,Sの平たんなグラフGは,次の条件を満たす最小の有向グラフと定義する。 

− SはGの中にある。 

− TがGの中にあり,かつTが値型Xであるようなインスタンスフィールドをもつ場合は常に,XはG

の中にあり,かつTからXへの辺がある。 

− TがGの中にあり,かつTが値型Yであるような静的フィールドをもつ場合は常に,YはGの中に

ある。 

例 

class C<U> { } 

struct S1<V> { 

  S1<V> x; 

struct S2<V> { 

  static S2<V> x; 

background image

163 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

struct S3<V> { 

  static S3<C<V>> x; 

struct S4<V> { 

  S4<C<V>>[] x; 

構造体型S1は有限であるが,循環で平たんなグラフをもち,不当となる。S2は有限で非循環

の平たんなグラフをもち,妥当となる。S3は,無限で非循環の平たんなグラフをもち,不当とな

る。S4は有限で非循環の平たんなグラフをもち,妥当となる。なぜならばフィールドS4<C<V>>.x

は,値型ではなく参照型をもつからである。 

C<U>型は,この例には必ずしも必要ではない。しかし,仮にそれが用いられなかった場合,次

の例が問題であるか否かが不明りょうとなる。 

struct S3<V> { 

  static S3<S3<V>> x; 

問題とはフィールド型の中で,内側又は外側にS3<...>が出現した場合である。 

13.1 値型の引用 

値型のボックス化解除された形式は,型参照の前にvaluetypeキーワードを使って,参照されなけれ

ばならない。値型のボックス化形式は,型参照の前にboxedキーワードを使って,参照されなければなら

ない。 

《値型参照》 ::=      
     boxed 《型参照》 
| valuetype 《型参照》 

13.2 値型の初期化 

クラスのように,値型は,インスタンス構築子(10.5.1参照)及び型初期化子(10.5.3参照)の両方をも

っていてもよい。nullに自動的に初期化されるクラスと異なり,次の規則が,(ボックス化解除された)値

型の初期化に関する唯一の保証をする。 

− 型がロードされるとき(10.5.3.3参照),静的変数は,ゼロに初期化されなければならない。したがっ

て,型が値型の静的なものは,その型がロードされるときにゼロで初期化される。 

− メソッドヘッダ(25.4.4参照)中のlocalsinitビットが設定される場合,局所変数はゼロに初期化

されなければならない。 

− 配列は,ゼロで初期化されなければならない。 

− クラスのインスタンス(すなわちオブジェクト)は,それらのインスタンス構築子を呼び出す前にゼ

ロで初期化されなければならない。 

注記 根拠としては,ボックス化解除された値型の自動初期化の保証は,特にスレッドで局所な記憶

域を採用し,スレッドをCLIの外部で生成してから, CLIに渡して管理させることが許されて

いるプラットフォーム上で,困難で費用がかかる。 

注記 ボックス化された値型は,クラスであり,クラスの規則に従う。 

命令initobj(第3章参照)は,プログラム制御下でゼロでの初期化を実行する。値型が構築子をもつ

場合,クラスを処理するように,そのボックス化解除された型のインスタンスを生成できる。命令newobj

164 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

(第3章参照)は,インスタンスを割り付けて初期化するために初期化子及びその仮引数とともに使用さ

れる。値型のインスタンスは,スタック上に割り付けられる。基底クラスライブラリは,ボックス化解除

された値型の配列中のすべてのインスタンスをゼロにするためのメソッドSystem.Array.Initialize

(第4章参照)を供給する。 

例 (参考): 

次のコードは,三つの値型変数を宣言及び初期化する。最初の変数は,ゼロで初期化される,

二番目は,インスタンス構築子の呼出しによって初期化される。そして,三番目は,スタック上

にオブジェクトを生成し及びそれを局所的に格納することによって初期化される。 

.assembly Test { } 

.assembly extern System.Drawing { 

  .ver 1:0:3102:0 

  .publickeytoken = (b03f5f7f11d50a3a) 

.method public static void Start() 

{ .maxstack 3 

  .entrypoint 

  .locals init (valuetype [System.Drawing]System.Drawing.Size Zero, 

          valuetype [System.Drawing]System.Drawing.Size Init, 

          valuetype [System.Drawing]System.Drawing.Size Store) 

  // Zeroは,Zeroという名前の局所変数を初期化する。 

  ldloca Zero           // 局所変数のアドレスを読み込む。 

  initobj valuetype [System.Drawing]System.Drawing.Size 

  // Initという名前の局所変数の初期化を呼び出す。 

  ldloca Init           // 局所変数のアドレスを読み込む。 

  ldc.i4 425            // 実引数1(幅)を読み込む。 

  ldc.i4 300            // 実引数2(高さ)を読み込む。 

  call instance void [System.Drawing]System.Drawing.Size::.ctor(int32, 

int32) 

  // スタック上に新しいインスタンスを生成し,Storeに格納する。 

// stobjは,ここで使用されることに注意する。しかし, stloc,stfldなどもまっ

たく同様に使用することができる。 

 ldloca Store 

  ldc.i4 425            // 実引数1(幅)を読み込む。 

  ldc.i4 300            // 実引数2(高さ)を読み込む。 

  newobj instance void 

[System.Drawing]System.Drawing.Size::.ctor(int32, int32) 

  stobj valuetype [System.Drawing]System.Drawing.Size 

background image

165 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

  ret 

13.3 値型のメソッド 

値型は,静的メソッド,インスタンスメソッド及び仮想メソッドをもっていてもよい。値型の静的メソ

ッドは,クラス型の静的メソッドと同じ方法で定義及び呼び出される。クラスと同様に,ボックス化され

た値型又はボックス化解除された値型のインスタンスメソッド及び仮想メソッドの両方は,命令callを

用いて呼び出されてもよい。命令callvirtは,ボックス化解除された値型(第1章参照)と一緒に使用

されてはならない。しかし,それはボックス化された値型に使用することができる。 

クラスのインスタンスメソッド及び仮想メソッドは,クラスのインスタンスへの参照がthis ポインタと

なるように符号化されなければならない。対照的に,値型のインスタンスメソッド及び仮想メソッドは,

値型のボックス化解除されたインスタンスへの管理下ポインタ(第1章参照)となるように符号化されな

ければならない。ボックス化された値型が,ボックス化解除された値型によって実装が提供される仮想メ

ソッドへのthisポインタとして渡される場合,CLIは,ボックス化された値型をボックス化解除された値

型への管理下ポインタに変換する。 

注記 この操作は,インスタンスのボックス化解除と同じとする。これは,命令unbox(第3章参照)

が,元のボックス化されたインスタンスとメモリを共有する値型への管理下ポインタを返却す

るために定義されることによる。 

次の図式群は,値型のボックス化及びボックス化解除の表現の関係を理解するのに役立つか

もしれない。 

注記 根拠としては,値型へのインスタンスメソッドの重要な使用法は,インスタンスの内部状態を

変更することによる。ボックス化解除された値型のインスタンスは,元の値ではなく値のコピ

ーに対して動作するから,それをthisポインタのために使用する場合,変更することはできな

い。ボックス化解除された値型が実引数として渡される場合,それらは複製される。 

仮想メソッドは,複数の型が実装コードを共有できるようにするために使用する。また,こ

れは,仮想メソッドを実装するすべてのクラスが最初にそのメソッドを導入するクラスによっ

て定義された共通の表現を共有することを要求する。値型は,インタフェース及び

System.Objectで定義された仮想メソッドを実装できる(そして基底クラスライブラリ内で

background image

166 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

行う)から,仮想メソッドがボックス化された値を用いて呼出し可能とすることは重要とする。

したがって,それは,インタフェースを実装する他の型と同様に操作されることができる。こ

れは,実行エンジンが仮想呼出し時に値型を自動的にボックス化解除するという要件を導く。 

表2−CIL命令によって与えられるthisの型及びインスタンスメソッドの型の宣言 

値型(ボックス化又はボックス化解除された) 

インタフェース 

クラス型 

call 

値型への管理下ポインタ。 

不当 

オブジェクト参照 

callvirt 

値型への管理下ポインタ。 

オブジェクト参照 

オブジェクト参照 

例 (参考): 

次は,値型int32の整数を文字列に変換する。基底クラスライブラリで定義された,ボックス

化解除された値型System.Int32にint32が対応することを思い起こす。整数が次のように宣

言されると仮定する。 

     .locals init (int32 x) 

その後,次に示されるように,その呼出しがなされる。 

     ldloca x 

// 局所変数への管理下ポインタのロード 

     call instance string  

          valuetype [mscorlib]System.Int32::ToString() 

しかし,System.Object(クラス)が,System.Int32(値型)ではなく型参照として使用

される場合,呼出しが作られる前にxの値は,ボックス化されなければならない。そのコードは

次のとおりとする。 

     ldloc x 

     box valuetype [mscorlib]System.Int32 

     callvirt instance string [mscorlib]System.Object::ToString() 

14 特殊な型の意味 

特殊な型とはCILから参照されるが,定義が与えられないものをいう。VESは,その参照によって取得

可能な情報に基づいて定義を自動的に提供する。 

14.1 ベクトル 

《型》 ::= …  
     | 《型》 ʻ[ʼ ʻ]ʼ 

ベクトルはゼロを下限とする1次元配列とする。これはCIL命令集合(newarr,ldelem,stelem及

び ldelema,第3章参照)によって直接提供される。CILフレームワークは,多次元配列及びゼロ以外

の値を下限とする1次元配列にも対応する方法を提供する(14.2参照)。二つのベクトルが同じ型であると

は,それら二つの実際の上限の値にかかわらず,要素型が同じ場合をいう。 

ベクトルは,固定の大きさ及び要素型をもつが,それらはベクトルが生成される時に決定される。すべ

てのCIL命令は,これらの値を尊重しなければならない。すなわち,それらCIL命令は,ベクトルの境界

を超える添字を指定しようとすること,ベクトルの要素に不正な型のデータを格納しようとすること,及

び不正なデータ型でベクトル要素のアドレスを取得しようとすることを確実に検出しなければならない

(第3章参照)。 

background image

167 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

例 文字列のベクトルを宣言する。 

.field string[] errorStrings 

関数ポインタのベクトルを宣言する。 

.field method instance void*(int32) [] myVec 

四つの文字列のベクトルを生成し,それをerrorStringフィールドに格納する。四つの文字

列は,errorStrings[0]からerrorStrings[3]に格納される。 

ldc.i4.4 

newarr string 

stfld string[] CountDownForm::errorStrings 

文字列”First”をerrorStrings[0]に格納する。 

ldfld string[] CountDownForm::errorStrings 

ldc.i4.0 

ldstr "First" 

stelem  

ベクトルはCLIで既に定義されている抽象クラスSystem.Arrayの下位型とする。それはすべてのベ

クトルに適用可能な幾つかのメソッドを提供する(第4章参照)。 

14.2 配列 

ベクトル(14.1参照)がCIL命令によって直接提供されるのに対し,これ以外のすべての配列は,抽象

クラスSystem.Arrayの下位型を生成してVESが提供する(第4章参照)。 

《型》 ::= … 
   | 《型》 ʻ[ʼ [《範囲》 [ ʼ,ʼ 《範囲》 ]*] ʻ]ʼ 

配列の次元数とは,次元の個数とする。CLIは次元数0の配列を提供しない。(ベクトル以外の)配列の

型は,その要素の型及び次元の個数で決定される。 

《範囲》 ::= 

記述 

  ʻ...ʼ 

下限及び上限は指定されない。多次元配列である場
合,省略記号を省略してもよい。 

| 《Int32》 

下限をゼロとし,上限を《Int32》とする。 

| 《Int32》 ʻ...ʼ 

下限だけの指定。 

| 《Int32》 ʻ...ʼ 《Int32》 

上下限両方の指定。 

VESが配列用に生成したクラスは,幾つかのメソッドを含むが,その実装はVESによって供給される。 

− int32型実引数列をとる構築子。それぞれの実引数は,配列の次元を表し,第1次元から始まり各次

元の要素の個数を指定する。下限についてはゼロが想定される。 

− 配列の次元数の2倍の個数のint32型実引数列をとる構築子。これら実引数は,一つの次元について

一対で出現する。各対の最初の実引数はその次元の下限を指定し,2番目の実引数はその次元の要素

の総数を指定する。ベクトルに対して下限はゼロが想定されるため,この構築子によって,ベクトル

は生成されないことに注意する。 

− int32型実引数列をとるGetメソッド。それぞれの実引数は配列の次元を表し,型がその配列の要

素型である値を返す。このメソッドは,配列の特定の要素にアクセスするために用いられる。その実

引数には,返される要素の各次元の添字を最初の次元から順に指定する。 

− int32型実引数列をとるSetメソッド。それぞれの実引数は配列の次元及びそれに続くもう一つの

168 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

配列の要素型をもつ値とする。Setの返却値の型はvoidとする。このメソッドは,配列の特定の要

素に値を設定するために用いられる。その実引数には,値を設定する要素の各次元の添字を最初の次

元から順に指定し,最後の実引数に対象要素に格納される値を指定する。 

− int32型実引数列をとるAddressメソッド。それぞれの実引数は配列の次元を表し,返却値の型は,

その配列の要素型への管理下ポインタ型とする。このメソッドは,配列の特定の要素を指す管理下ポ

インタを返すために用いられる。その実引数には,返却されるアドレスに存在する要素の各次元の添

字を最初の次元から順に指定する。 

例 次の例では,添字5…10及び3…7を添字指定する2次元文字列配列MyArrayを生成する。引き

続き文字列”One”をMyArray[5, 3]に格納し,それを取り出して,印字する。次にMyArray[5, 

4]のアドレスを計算し,”Test”をそこに格納し,その値を取り出して,印字する。 

.assembly Test { } 

.assembly extern mscorlib { } 

.method public static void Start() 

{ .maxstack 5 

  .entrypoint 

  .locals (class [mscorlib]System.String[,] myArray) 

  ldc.i4.5 // load lower bound for dim 1 

  ldc.i4.6 // load (upper bound - lower bound + 1) for dim 1 

  ldc.i4.3 // load lower bound for dim 2 

  ldc.i4.5 // load (upper bound - lower bound + 1) for dim 2 

  newobj instance void string,[,]::.ctor(int32, int32, int32, int32) 

  stloc  myArray 

  ldloc myArray 

  ldc.i4.5 

  ldc.i4.3 

  ldstr "One" 

  call instance void string,[,]::Set(int32, int32, string) 

  ldloc myArray 

  ldc.i4.5 

  ldc.i4.3 

  call instance string string,[,]::Get(int32, int32) 

  call void [mscorlib]System.Console::WriteLine(string) 

  ldloc myArray 

  ldc.i4.5 

  ldc.i4.4 

  call instance string & string,[,]::Address(int32, int32) 

  ldstr "Test" 

  stind.ref 

  ldloc myArray 

  ldc.i4.5 

background image

169 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

  ldc.i4.4 

  call instance string string,[,]::Get(int32, int32) 

  call void [mscorlib]System.Console::WriteLine(string) 

  ret 

注記 ここから参考情報であり規定ではない。 

多次元配列の要素は連続するメモリ領域に配置されていると考えることができるが,一方,配列の配列

はこれと異なる。(最後を除き)各次元は配列参照を保持する。次の図はその違いを例示する。 

左側は,[6, 10]の一つの長方形配列である。右側は一つではなく,全部で五つの配列である。垂直に描

かれた配列は,配列の配列であり,水平に描かれた四つの配列を参照している。垂直配列の第1要素及び

第2要素は,ともに同じ水平配列を参照していることに注意する。 

多次元配列におけるすべての次元は,同じ大きさでなければならないことに注意する。これに対し配列

の配列は,異なる大きさの配列を参照することも可能である。例えば,右の図では,垂直配列が長さ8,8,

3,null(すなわち配列を参照していない),6及び1の配列を参照していることを表現する。 

このようないわゆる非長方形配列(jagged array)に対する特別な実装は,CIL命令集合にもVESにもな

い。それは単に,(再帰的に)他の非長方形配列を参照するベクトルである。 

注記 参考情報終わり 

14.3 enum 

enum(列挙型)は,enumeration(列挙)の短縮形であり,すべて同じ型をもつ記号の集合を定義する。

型が列挙型であるとは,それがSystem.Enumを直接の基底型をもつことと同値とする。System.Enum

それ自身は,System.ValueTypeを直接の基底型をもつため(第4章参照),列挙型は値型となる(箇条

13参照)。enumの記号は,基礎とする整数型によって表現される。すなわち,次のいずれかとなる。 

bool,char,int8,unsigned int8,int16,unsigned int16,int32,unsigned int32,

int64,unsigned int64,native int,unsigned native int 

注記 Pascal言語と異なり,CLIは,列挙型の値が記号の一つに対応する整数であるということを保

障しない。実際,CLS(第1章CLS参照)は,列挙型をビットフラグで表して使用する規約を

提供する。このビットフラグは列挙型自身によって名前を付けられていない整数値を形成する

ように,値を組み合わせることができる。 

列挙型は,他の値型を超える追加の制約を負っている。列挙型は,メンバとしてフィールドだけを含ま

なければならない(それは型の初期化子又はインスタンス構成子すら定義してはならない。)。列挙型は,

インタフェースを実装してはならない。列挙型は,自動フィールド配置をもたなければならない(10.1.2

参照)。列挙型は,ちょうど一つのインスタンスフィールドをもたなければならず,かつ,それはその列挙

170 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

型が基礎とする型でなければならない。その他のすべてのフィールドは静的,かつ,リテラルでなければ

ならない(16.1参照)。さらに,列挙型は,intobj命令によって初期化されてはならない。 

注記 根拠は次のとおりである。これらの制約によって列挙型の非常に効率的な実装が可能となる。 

単一の必す(須)のインスタンスフィールドは,列挙型のインスタンスの値を格納する。列挙型の静的

なリテラルフィールドは,列挙型の記号から基礎とする値への写像を宣言する。これらすべてのフィール

ドは,enumの型をもたなければならず,かつ,フィールドに値を割り当てるフィールド初期化メタデー

タをもたなければならない(16.2参照)。 

結合を目的として(例えば,それを呼び出すのに使われるメソッド参照からメソッド定義を特定するた

め。)列挙型は,それが基礎とする型と区別されなければならない。コードの検証及び実行を含め,これ以

外の目的のために,ボックス化されていない列挙型は,それが基礎とする型と,自由に相互変換してよい。

列挙型は対応するボックス化されたインスタンス型へボックス化されることができるが(箇条13参照),

しかしその型は,基礎とする型がボックス化された場合の型と同じではない。したがってボックス化によ

って,列挙型の元の型を失うことはない。 

例 ここに示す例は,次のことを行う。すなわち,列挙型を宣言し,次にその型の局所変数を生成す

る。そのenumに基礎とする型の定数を格納する(これによって基礎とする型からenum型への

自動型変換が起こることを示している。)。そのenumを再ロードし,基礎とする型として印字す

る(これによって逆自動型変換を示している。)。最後に,そのenumのアドレスをロードし,イ

ンスタンスフィールドの内容を抽出し,同様にそれを印字する。 

.assembly Test { } 

.assembly extern mscorlib { } 

.class sealed public ErrorCodes extends [mscorlib]System.Enum 

{ .field public unsigned int8 MyValue 

  .field public static literal valuetype ErrorCodes no̲error = int8(0) 

  .field public static literal valuetype ErrorCodes format̲error = 

int8(1) 

  .field public static literal valuetype ErrorCodes overflow̲error = 

int8(2) 

  .field public static literal valuetype ErrorCodes nonpositive̲error 

= int8(3) 

.method public static void Start() 

{ .maxstack 5 

  .entrypoint 

  .locals init (valuetype ErrorCodes errorCode) 

  ldc.i4.1           // load 1 (= format̲error) 

  stloc errorCode    // store in local, note conversion to enum 

  ldloc errorCode 

  call void [mscorlib]System.Console::WriteLine(int32) 

  ldloca errorCode   // address of enum 

  ldfld unsigned int8 valuetype ErrorCodes::MyValue 

background image

171 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

  call void [mscorlib]System.Console::WriteLine(int32) 

  ret 

14.4 ポインタ型 

《型》 ::= … 

細分箇条 

   | 《型》 ʻ&ʼ  

14.4.2 

   | 《型》 ʻ*ʼ 

14.4.1 

ポインタ型は,それが指し示す場所の型を含む識別情報を指定することで定義される。ポインタは,管

理下(CLIごみ集めに報告されるものであり,&で表される。14.4.2参照)であっても,又は管理外(CLI

ごみ集めに報告されないものであり,*で表される。14.4.1参照)であってもよい。 

ポインタは,(オブジェクト若しくは値型の)フィールドのアドレス又は配列の要素に対するアドレスを

含んでもよい。ポインタは,完全な型インスタンスを指し示さないが,インスタンスの内部を指し示す点

でオブジェクト参照とは異なる。CLIは,ポインタに対する二つの型安全な操作を提供する。 

− ポインタによって参照される場所からの値のロード 

− ポインタによって参照される場所への,代入互換な値の格納 

同じ配列又は同じオブジェクト(第1章参照)へのポインタに対して,次の算術演算が用意されている。 

− ポインタに整数値を加える。ここで,その整数値はバイト数と解釈され,演算結果として同じ種類の

ポインタを生じる。 

− ポインタから整数値(バイト数)を引く。ここで,その整数値はバイト数と解釈され,演算結果とし

て同じ種類のポインタを生じる。整数値からポインタを引くことについては許可されていないことに

注意する。 

− 二つのポインタは,その種類にかかわらず,一方から他方を引くことができ,それらが参照している

アドレス間のバイト数を表現する整数値を生成する。 

注記 ここから参考情報であり規定ではない。 

ポインタは,32ビットアーキテクチャでは,unsigned int32と,64ビットアーキテクチャでは

unsigned int64と互換となる。それは,大きさが実行時計算機アーキテクチャに依存して変化する

unsigned intと考えるのが一番よい。 

CIL命令集合(第3章参照)は,フィールド,局所変数,実引数及びベクトルの要素に対するアドレス

を計算する命令を含んでいる。 

命令 

記述 

ldarga 

実引数のアドレスをロードする 

ldelema 

ベクトル要素のアドレスをロードする 

ldflda 

フィールドのアドレスをロードする 

ldloca 

局所変数のアドレスをロードする 

ldsflda 

静的フィールドのアドレスをロードする 

ポインタがスタックにロードされると,データ項目をそれが指し示す位置にロードするためにldind

クラスの命令を使ってもよい。同様に,その場所にデータを格納するためには,stindクラスの命令を使

うことができる。 

CLIは,アドレスが現在のアプリケーション領域の中にない場合に,ldflda命令を使用すると

InvalidOperationException例外を送出することに注意する。この状況は, 

System.MarshalByRefObjectの基底型をもつオブジェクトを使用した場合に限り,典型的に発生する

172 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

(第4章参照)。 

注記 参考情報終わり 

14.4.1 管理外ポインタ 

注記 この細分箇条は参考情報であり規定ではない。 

管理外ポインタ(*)は,C及びC++のような言語で使用される伝統的なポインタとする。それは大部

分検証不能のコードを生じるが,その使用には何ら制約はない。管理外ポインタを含む位置を,符号なし

整数であるかのように印付けることは,完全に妥当であるが(そして実際それは,VESの取扱い方と同じ

であるが),しかし,通常管理外ポインタを特定の型のデータとして印付けるほうがよい。これは返却値,

局所変数,若しくは実引数に対する識別情報に*を使用することによって,又はフィールド若しくは配列

要素に対してポインタ型を使用することによってなされる。 

− 管理外ポインタは,ごみ集め子に報告されることはなく,整数が使用されるのと同様に使用すること

ができる。 

− 正当性検証可能なコードは,管理外ポインタの参照をたぐることはできない。 

− 正当性検証されないコードは,管理下ポインタを要求するメソッドに対して管理外ポインタを渡すこ

とができる。これが安全なのは次のいずれか一つが真である場合に限る。 

− 管理外ポインタが,CLIによってオブジェクトのインスタンス(ごみ集めされたメモリ又は管理下

メモリ)を格納するために使用されたメモリ以外のメモリを参照する。 

− 管理外ポインタが,オブジェクト内のフィールドのアドレスを含む。 

− 管理外ポインタが,配列内の要素のアドレスを含む。 

− 管理外ポインタが,配列の最後の要素に引き続く要素があるはずの位置のアドレスを含む。 

14.4.2 管理下ポインタ 

注記 この細分箇条は参考情報であり規定ではない。 

管理下ポインタ(&)は,値型のインスタンス,オブジェクトのフィールド,値型のフィールド,配列

の要素,又は(管理下配列内に添字指定するポインタとして)配列最終要素の直後の要素が格納されるア

ドレスを指してもよい。管理下ポインタは,nullにできず,かつ,それが管理下メモリを指していない場

合でも,ごみ集め子に報告されなければならない。 

管理下ポインタは,返却値,局所変数,若しくは実引数の識別情報に&を用いることで,又はフィール

ド若しくは配列要素に対し,byref型を用いることで指定される。 

− 管理下ポインタは,実引数として渡すこと,局所変数に格納すること,及び値として返却することが

できる。 

− 仮引数が参照渡しである場合,対応する実引数は管理下ポインタとする。 

− 管理下ポインタは,静的変数,配列要素,又はオブジェクト若しくは値型のフィールドに格納するこ

とができない。 

− 管理下ポインタは,オブジェクト参照と相互変換可能ではない。 

− 管理下ポインタは,別の管理下ポインタを指すことはできないが,オブジェクト参照又は値型を指す

ことはできる。 

− 管理下ポインタは,局所変数又はメソッドの実引数を指すことができる。 

− 管理下メモリを指していない管理下ポインタは(conv.u又はconv.ovf.uを用いて)管理外ポイン

タに変換することができるが,この変換によって正当性検証可能ではなくなる。 

− 管理下ポインタから管理外ポインタに誤って変換された検証されないコードは,CLIの整合性を著し

background image

173 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

く汚す。詳細は第3章(管理下ポインタ)を参照。 

14.5 メソッドポインタ 

《型》 ::= … 

   | method 《呼出し規約》 《型》 ʻ*ʼ ʻ(ʼ 《仮引数群》 ʻ)ʼ 

メソッドポインタ型の変数は,互換な識別情報をもつメソッドへの入口点のアドレスを格納する。静的

メソッド又はインスタンスメソッドへのポインタは,ldftn命令によって得られるが,一方仮想メソッド

へのポインタは,ldvirtftn命令によって得られる。メソッドは,メソッドポインタを用いてcalli命

令によって呼び出してもよい。これらの命令の規定については,第3章を参照。 

注記 他のポインタと同様,メソッドポインタは,64ビットアーキテクチャでは,unsigned int64

と,32ビットアーキテクチャでは,unsigned int32と互換とする。しかし,好ましい用い

方は,unsigned native intを用いることであり,これは32ビット及び64ビット両方の

アーキテクチャで動作する。 

例 この例は,ポインタを用いてメソッドを呼び出している。メソッドMakeDecision::Decide

は,呼出しごとに交互にAddOne又はNegateのうちいずれかへのメソッドポインタを返す。主

プログラム(main)は,MakeDecision::Decideを3回呼び出し,各呼出しの後,指定された

メソッドを呼び出すためにcalli命令を用いている。印字される出力は,正常な交互呼出しを示

す”-1 2 -1”となる。 

.assembly Test { } 

.assembly extern mscorlib { } 

.method public static int32 AddOne(int32 Input) 

{ .maxstack 5 

  ldarg Input 

  ldc.i4.1 

  add 

  ret 

.method public static int32 Negate(int32 Input) 

{ .maxstack 5 

  ldarg Input 

  neg 

  ret 

.class MyValue sealed public MakeDecision extends 

   [mscorlib]System.ValueType 

{ .field static bool Oscillate 

  .method public static method int32 *(int32) Decide() 

  { ldsfld bool valuetype MakeDecision::Oscillate 

    dup 

    not 

    stsfld bool valuetype MakeDecision::Oscillate 

174 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

    brfalse NegateIt 

    ldftn int32 AddOne(int32) 

    ret 

NegateIt: 

    ldftn int32 Negate(int32) 

    ret 

  } 

.method public static void Start() 

{ .maxstack 2 

  .entrypoint 

  ldc.i4.1 

  call method int32 *(int32) valuetype MakeDecision::Decide() 

  calli int32(int32) 

  call  void [mscorlib]System.Console::WriteLine(int32) 

  ldc.i4.1 

  call method int32 *(int32) valuetype MakeDecision::Decide() 

  calli int32(int32) 

  call  void [mscorlib]System.Console::WriteLine(int32) 

  ldc.i4.1 

  call method int32 *(int32) valuetype MakeDecision::Decide() 

  calli int32(int32) 

  call  void [mscorlib]System.Console::WriteLine(int32) 

  ret 

14.6 委譲 

委譲(第1章参照)とは,オブジェクト指向において,関数ポインタに相当するものである。関数ポイ

ンタとの違いは,委譲がオブジェクト指向,型安全,かつ,安全(secure)な点にある。委譲は,参照型

であり,クラスの形式で宣言される。委譲はSystem.Delegateの基底型をもたなければならない(第4

章参照)。 

委譲は,封印宣言されなければならず,委譲がもたなければならないメンバは,ここで指定される最初

の二つ又は四つのメソッドすべてだけとする。これらのメソッドは,runtimeかつmanagedと宣言され

なければならない(15.4.3参照)。それらの本体はVESによって自動的に生成されなければならないため,

それらは本体をもってはならない。委譲において,利用可能な他のメソッドは,基底クラスライブラリ内

のクラスSystem.Delegateから継承される(第4章参照)。この委譲メソッドは,次のとおりとする。 

− インスタンス構築子(.ctorで名前付けされ,かつ,specialname及びrtspecialnameで印付け

されたもの,10.5.1参照)は,ちょうど二つの仮引数を取らなければならない。第1仮引数は,型

System.Objectでなければならず,第2仮引数は,型System.IntPtrでなければならない。実際

に(newobj命令によって,第3章参照)呼び出される時には,第1実引数は対象メソッドを定義す

るクラス(又はその派生クラスの一つ)のインスタンスでなければならず,第2実引数は呼び出され

175 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

るメソッドへのメソッドポインタでなければならない。 

− Invokeメソッドは,virtualでなければならず,かつ,その識別情報は,対象となるメソッドを含

まなければならない。そのメソッドはその識別情報と結合することができる。14.6.1参照。検証系は,

委譲におけるInvokeメソッドの呼出しを,それ以外の任意のメソッドの呼出と全く同様に扱う。 

− BeginInvokeメソッド(14.6.3.1参照)は,もしあればvirtualでなければならず,かつ,Invoke

メソッドの識別情報と同一ではないが関連のある識別情報をもたなければならない。その識別情報に

は二つの差異がある。第1に,返却値の型は,System.IAsyncResult(第4章参照)でなければな

らない。第2に,Invokeがとる仮引数に加えて二つの仮引数を取らなければならない。一つめの仮

引数の型はSystem.AsyncCallbackとし,二つめの仮引数の型はSystem.Objectとする。 

− EndInvokeメソッド(14.6.3参照)は,virtualでなければならず,かつ,Invokeメソッドと同

じ返却値の型をもたなければならない。それは仮引数として,Invokeの管理下ポインタである仮引

数と同一のものを,その識別情報に出現するのと同じ順序で取らなければならない。さらに,型

System.IAsyncResultの追加の仮引数を一つ取らなければならない。 

特に明記しない限り, 標準の委譲型は二つの省略可能な非同期メソッドBeginInvoke及び

EndInvokeを提供しなければならない。 

例 次の例では,一つの整数を取り,返却値をもたない関数群を呼び出すために使われる委譲を宣言

している。ここでは,四つのメソッドすべてを提供しているため,委譲を同期的にも,非同期的

にも呼び出すことができる。参照によって(すなわち管理下ポインタとして)渡される仮引数が

ないので,EndInvokeには追加の実引数は必要ない。 

.assembly Test { } 

.assembly extern mscorlib { } 

.class private sealed StartStopEventHandler extends 

[mscorlib]System.Delegate 

 { .method public specialname rtspecialname instance void .ctor(object 

Instance, 

          native int Method) runtime managed {} 

   .method public virtual void Invoke(int32 action) runtime managed {} 

   .method public virtual class [mscorlib]System.IAsyncResult  

        BeginInvoke(int32 action, class [mscorlib]System.AsyncCallback 

callback, 

           object Instance) runtime managed {} 

   .method public virtual void EndInvoke(class  

        [mscorlib]System.IAsyncResult result) runtime managed {} 

任意のクラスと同様,インスタンスはインスタンス構築子とともにnewobj命令を用いて生成される。構

築子に対する第1実引数は,メソッドを呼び出す対象のオブジェクトでなければならないか,又はメソッ

ドが静的メソッドである場合,nullでなければならない。第2実引数は,対応するクラスのメソッドへの

メソッドポインタでなければならず,かつ,インスタンス化される委譲クラスの識別情報と一致する識別

情報をもたなければならない。 

14.6.1 委譲識別情報の互換性 

176 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

委譲は,対象となるメソッドとだけ結合することができる。ここで,委譲及びその対象となるメソッド

の識別情報は互換とする。互換性は,仮引数の型,返却値の型,及び呼出し規約を検査することで決定さ

れる(カスタム修飾子は,重要ではないとみなすため,互換性に影響を及ぼさない。)。 

委譲及びその対象となるメソッドが互換となるためには,呼出し規約は完全に一致しなければならない。 

委譲及びその対象となるメソッドが互換となるためには,仮引数は次の規則に従い互換でなければなら

ない。 

D及びTを,委譲及びその対象となるメソッドの仮引数の型を(それぞれ)示すのに用いる。D:=Tを

仮引数の型が互換であることを表すために用いる。D!=Tを仮引数の型が互換でないことを表すために用い

る。D[]を型Dの配列を表すために用いる。総称型G<V>のインスタンス化Dに対し,VDをVに用いられ

た型仮引数を表すために用いる。 

1) [:=は反射律をもつ]任意の仮引数型Dについて,D:=D。 

2) [:=は推移律をもつ]任意の仮引数型D,T及びUについて,D:=U及びU:=Tが成り立つならば,D:=T

が成り立つ。 

3) D:=Tが成り立つのは,TがDの基底クラス,又はDによって実装されたインタフェースであって,

かつDが(基本型,ポインタ型,関数ポインタ型を含む)値型でないときとする。 

4) D:=Tが成り立つのは,D及びTがともにインタフェースであって,かつDの実装が Tの実装を必要

とするときとする。 

5) D[]:=T[]が成り立つのは,D:=Tであって,かつ配列がともに(ゼロを基底とし,次元数が1の)ベク

トルであるか,又はいずれもがベクトルでなく,かつともに同じ次元数をもつときとする。 

6) D及びTがメソッドポインタのとき,D:=Tが成り立つのは,識別情報(仮引数の型,返却値の型,呼

出し規約,カスタム修飾子)がこれらの規約によって互換であるときとする。 

7) D:=Tが成り立つのは,D及びTが総称型G<+V>のインスタンス化であって,かつVDがVTの下位型

のときとする。 

8) D:=Tが成り立つのは,D及びTが総称型G<-V>のインスタンス化であって,かつVTがVDの下位型

のときとする。 

9) D:=Tが成り立つのは,D及びTが総称型G<V>のインスタンス化であって,かつVd==Vtのときとす

る。 

10) 上記以外の場合,D!=Tとする。 

委譲及びその対象となるメソッドが互換となるには,返却値の型が次の規則に従って互換でなければな

らない。D及びTを,委譲及びその対象となるメソッドの返却値の型を(それぞれ)表すのに用いる。D:=T

を返却値の型が互換であることを表すために用いる。D!=Tを返却値の型が互換でないことを表すために用

いる。D[]を型Dの配列を表すために用いる。総称型G<V>のインスタンス化Dに対しVD は,Vに用い

られた型仮引数を表す。 

1) [:=は,反射律をもつ]任意の返却値の型Dについて,D:=D。 

2) [:=は,推移律をもつ]任意の返却値の型D,T及びUについて,D:=U及びU:=Tが成り立つならば,

D:=Tが成り立つ。 

3) D:=Tが成り立つのは,TがDの基底クラス又はDによって実装されたインタフェースであって,か

つDが(基本型,ポインタ型,関数ポインタ型を含む)値型でないときとする。 

4) D:=Tが成り立つのは,D及びTがともにインタフェースであって,かつTの実装がDの実装を必要

とするときとする。 

177 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

5) D[]:=T[]が成り立つのは,D:=Tであって,かつ配列がともに(ゼロを基底とし,次元数が1の)ベク

トルであるか,又はいずれもがベクトルでなく,かつともに同じ次元数をもつときとする。 

6) D及びTがメソッドポインタであるとき,D:=Tが成り立つのは,識別情報(仮引数の型,返却値の型,

呼出し規約,カスタム修飾子)がこれらの規則によって互換であるときとする。 

7) D:=Tが成り立つのは,D及びTが総称型G<+V>のインスタンス化であって,かつVTがVDの下位型

のときとする。 

8) D:=Tが成り立つのは,D及びTが総称型G<-V>のインスタンス化であって,かつVDがVTの下位型

のときとする。 

9) D:=Tが成り立つのは,D及びTが総称型G<V>のインスタンス化であって,かつVD==VTのときとす

る。 

10) 上記以外の場合,D!=Tとする。 

14.6.2 委譲の同期呼出し 

委譲呼出しの同期モードは,通常のメソッド呼出しに対応し,かつ,それは委譲においてInvokeと名

前付けられた仮想メソッドを呼び出すことによってなされる。委譲それ自身が,この呼出しにおける第1

実引数であり,次にその他の実引数が,識別情報に指定されたとおりに続く。この呼出しが行われると,

呼出し側は,呼び出されたメソッドから戻るまで,実行をブロックしなければならない。呼び出されたメ

ソッドは,呼出し側と同一のスレッド上で実行されなければならない。 

例 直前の例に続き,委譲の対象としての使用にふさわしいメソッドonStartStopを宣言するクラ

スTestを定義する。 

.class public Test 

{ .field public int32 MyData 

  .method public void onStartStop(int32 action) 

  { ret        // put your code here 

  } 

  .method public specialname rtspecialname  

          instance void .ctor(int32 Data) 

  { ret        // call superclass constructor, store state, etc. 

  } 

次に主プログラム(main)を定義する。これは,まずTestのインスタンスを構築し,次にそ

のインスタンスのonStartStopメソッドを対象とする委譲を構築する。最後にその委譲を呼び

出す。 

.method public static void Start() 

{ .maxstack 3 

  .entrypoint 

  .locals (class StartStopEventHandler DelegateOne, 

           class Test InstanceOne) 

  // Create instance of Test class 

  ldc.i4.1 

  newobj instance void Test::.ctor(int32) 

178 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

  stloc InstanceOne 

  // Create delegate to onStartStop method of that class 

  ldloc InstanceOne 

  ldftn instance void Test::onStartStop(int32) 

  newobj void StartStopEventHandler::.ctor(object, native int) 

  stloc DelegateOne 

  // Invoke the delegate, passing 100 as an argument 

  ldloc DelegateOne 

  ldc.i4 100 

  callvirt instance void StartStopEventHandler::Invoke(int32) 

  ret 

上の例では,非仮想関数に対する委譲が生成されたことに注意する。onStartStopが仮想関

数だったとすれば,次のコード列を代わりに用いる。 

ldloc InstanceOne 

dup 

ldvirtftn instance void Test::onStartStop(int32) 

newobj void StartStopEventHandler::.ctor(object, native int) 

stloc DelegateOne 

// Invoke the delegate, passing 100 as an argument 

ldloc DelegateOne 

注記 上のコード列は,dupを使い,ldloc InstanceOneを2度使ってはならない。dupによるコ

ード列は,簡単に型安全であると認識されるのに対し,代替案ではより複雑な解析が必要とな

る。コードの正当性検証可能性については,第3章で規定する。 

14.6.3 委譲の非同期呼出し 

非同期モードでは,呼出しはディスパッチされ,呼出し側はメソッドからの戻りを待つことなく実行を

継続しなければならない。呼び出されたメソッドは,独立したスレッド上で実行されなければならない。 

委譲を非同期に呼び出すためには,BeginInvokeメソッド及びEndInvokeメソッドを用いる。 

注記 呼出し側のスレッドが,呼出し先の実行完了前に終了する場合でも,呼出し先のスレッドは影

響を受けない。呼出し先のスレッドは実行を継続し,終了する。 

注記 呼出し先は例外を送出してもよい。処理されない例外はすべて,EndInvokeメソッドを通し

て呼出し側へ伝ぱ(播)する。 

14.6.3.1 BeginInvokeメソッド 

委譲の非同期呼出しは,BeginInvokeメソッドの仮想呼出しによって開始しなければならない。

BeginInvokeは,Invokeメソッド(14.6.1参照)と類似であるが,二つの相違点がある。 

− それは,型System.AsyncCallback及び型System.Objectの二つの追加の仮引数を,リストの

最後にもつ。 

− メソッドの返却値の型は,System.IAsyncResultとする。 

BeginInvokeメソッドは,返却値を表す仮引数を含んではいるが,しかしこれらの値は,このメソッ

background image

179 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

ドでは更新されない。代わりに結果は,EndInvokeメソッドによって得られる(14.6.3.2参照)。 

同期呼出しと異なり非同期呼出しは,呼出し側に対し,その呼出しがいつ終了したのかを判定する手段

を提供しなければならない。CLIはそのために二通りの機構を提供している。第1はその呼出しから返さ

れる結果によるものである。このオブジェクトは,インタフェースSystem.IAsyncResultのインスタ

ンスであり,結果が計算されるまで待つために用いることができる。それはまた,メソッド呼出しの現在

の状態を問い合わせるために用いることができる。それは,更に,BeginInvokeを呼び出すために渡さ

れるSystem.Objectの値を含んでいる。第4章を参照。 

第2の機構は,BeginInvokeに渡されるSystem.AsyncCallbackの委譲によるものである。VES

は,値が計算された場合か,又は結果が得られなかったことを示すための例外が発生させられた場合に,

この委譲を呼び出さなければならない。このコールバックに対して渡される値は,BeginInvokeの呼出

しに対して渡される値と同一とする。VESがコールバックを提供する必要がないことを示すために,

System.AsyncCallbackに対してnull値が渡されてもよい。 

注記 根拠は次のとおりである。このモデルは(返されるSystem.IAsyncResultの状態を検査す

ることによる)ポーリング方式及び(System.AsyncCallbackを供給することによる)イベ

ント駆動方式の両方を提供する。 

同期呼出しは,その返却値及び出力仮引数の両方を通して情報を返す。出力仮引数は,CLIでは,管理

下ポインタ型をもつ仮引数として表現される。返却値及び出力仮引数の値の両方は,VESが非同期呼出し

が正常終了したことを通知するまでは,有効でない。それらは,非同期呼出しを開始した委譲の

EndInvokeメソッドを呼び出すことによって,取り出される。 

14.6.3.2 EndInvokeメソッド 

EndInvokeメソッドは,BeginInvoke後の任意の時点で呼び出すことができる。それは,非同期呼出

しが完了するまでの間,それを呼び出したスレッドの実行を中断しなければならない。呼出しが正常に完

了した場合,EndInvokeは,その呼出しが同期的になされた場合に返却する値を返し,かつ,その管理

下ポインタ実引数は,対応する同期呼出しの出力仮引数に返却される値を指す。 

EndInvokeは,(委譲は複数同時に実行してもよいため,同じ委譲に対する異なる呼出しを区別できる

ように)対応するBeginInvokeの呼出しによって返される値を仮引数として必要とし,更に,渡される

管理下ポインタ(これによって委譲に対する返却値を供給できる)を実引数として必要とする。 

15 メソッドの定義,参照,及び呼出し 

メソッドは,大域的レベル(任意の型の外側)で定義してよい。 

《宣言》 ::= … 

   | .method 《メソッドヘッダ》 ʻ{ʼ 《メソッド本体項目》* ʻ}ʼ 

型の内側も同様。 

《クラスメンバ》 ::= … 

   | .method 《メソッドヘッダ》 ʻ{ʼ 《メソッド本体項目》* ʻ}ʼ 

15.1 メソッド記述子 

メソッドに関連付けられたILAsmには四つの構成要素がある。これらは,箇条23で述べられるとおり,

異なるメタデータ構成要素に対応する。 

15.1.1 メソッド宣言 

《メソッド宣言》,すなわち,メソッド宣言は,メソッド名及び識別情報(仮引数及び返却値の型)を与

180 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

えるが,その本体は与えない。すなわち,メソッド宣言は,《メソッドヘッダ》を与えるが,《メソッド本

体項目》は与えない。これらは,呼出し元にて呼出し対象を(call又はcallvirt命令によって,第3

章参照)指定するため,又は抽象メソッドを宣言するために使用される。《メソッド宣言》は,メタデー

タ内に直接的論理的対応部分をもたない。それは《メソッド定義》又は《メソッド参照》のいずれでもよ

い。 

15.1.2 メソッド定義 

《メソッド定義》,すなわち,メソッド定義は,メソッド名,属性,識別情報,及び本体を与える。すな

わち,メソッド定義は,《メソッドヘッダ》を与えるとともに一つ以上の《メソッド本体項目》も与える。

本体は,メソッドのCIL命令,例外ハンドラ,局所変数情報,及びそのメソッドに関する付加的な実行時

メタデータ又はカスタムメタデータを含む(箇条10参照)。 

15.1.3 メソッド参照 

《メソッド参照》,すなわち,メソッド参照は,メソッドへの参照とする。それは,定義が別のモジュー

ル又はアセンブリに存在するメソッドを呼び出す時に用いられる。《メソッド参照》は,そのメソッドが実

行時に呼び出されるまでに,VESによって《メソッド定義》として解決されなければならない。対応する

《メソッド定義》が見つからない場合,VESは,System.MissingMethodExceptionを送出する(22.25

参照)。 

15.1.4 メソッド実装 

《メソッド実装》,すなわち,メソッド実装は,既存の仮想メソッドに対する実行可能な本体を与える。

それは,(本体を表現する)《メソッド定義》と(仮想メソッドを表現する)《メソッド宣言》又は《メソッ

ド定義》とを関連付ける。《メソッド実装》は,継承された仮想メソッドの実装,又は,省略時の機構(名

前及び識別情報による一致)が正当な結果を提供しない場合に,インタフェースからの仮想メソッドの実

装を提供するために使用される(22.27参照)。 

15.2 静的メソッド,インスタンスメソッド及び仮想メソッド 

静的メソッドは,型と関連付けられ,そのインスタンスとは関連付けられないメソッドとする。 

インスタンスメソッドは,型のインスタンスと関連付けられたメソッドとし,インスタンスメソッドの

本体内において,そのメソッドが(thisポインタを用いて)操作している特定のインスタンスを参照する

ことが可能となる。したがって,インスタンスメソッドは,クラス内又は値型内でだけ定義することがで

きるのであって,インタフェース内又は型の外側(大域的)では定義できない。しかし,次に注意する。 

1) クラス(ボックス化された値型を含む)のインスタンスメソッドは,thisポインタをもち,それは

省略時解釈によってメソッドが定義されたクラスへのオブジェクト参照となる。 

2) (ボックス化解除された)値型のインスタンスメソッドは,thisポインタをもち,それは省略時解

釈によってメソッドが定義された型のインスタンスへの管理下ポインタとなる。 

3) thisポインタの型を指定するための(呼出し規約中で構文項目explicitを用いて示される。15.3

参照)特殊な符号化があり,ここで指定された省略時の値を上書きする。 

4) thisポインタはnullであってもよい。 

仮想メソッドは,インスタンスメソッドとほとんど同じ方法で,型のインスタンスと関連付けられる。

しかし,インスタンスメソッドと異なり,仮想メソッドは,その実装をVESがthisポインタに使用されて

いるオブジェクトの型に従って実行時に選択されなければならないという方法で,その仮想関数を呼び出

すことができる。仮想メソッドを実装する特定の《メソッド定義》は,callvirt命令を通して呼び出さ

れる時に,実行時に(仮想呼出しによって)動的に決定される。一方,call命令で呼び出される時,そ

background image

181 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

の結合は,コンパイル時に決定される(第3章参照)。 

仮想呼出し(だけ)において,継承の記法が重要となる。派生クラスは,その基底クラスから継承した

仮想メソッドを上書きしてもよい。これによって,そのメソッドの新しい実装を提供する。メソッド属性

newslotは,CLIが基底型の仮想メソッド定義を上書きしてはならず,その新しい定義を独立の仮想メソ

ッド定義として取り扱わなければならないことを指定する。 

抽象仮想メソッド(これは抽象クラス内又はインタフェース内においてだけ定義できるものである。)は,

callvirt命令によってだけ呼び出すことができる。同様に,抽象仮想メソッドのアドレスは,ldvirtftn

だけによって計算できるものとし,ldftn命令は用いてはならない。 

注記 根拠は次のとおりである。具象仮想メソッドには,その定義を含むクラスから利用できる実装

が常に存在する。したがって,利用できるクラスのインスタンスを実行時に用意する必要はな

い。しかし,抽象仮想メソッドは,下位型又は適切なインタフェースを実装するクラスだけか

ら,その実装を受け取る。したがって,メソッドを実際に実装するクラスのインスタンスが要

求される。 

15.3 呼出し規約 

《呼出し規約》 ::= [ instance [ explicit ]] [《呼出し種別》 ] 

呼出し規約は,メソッドの実引数が,呼出し側から呼び出されるメソッドにどのように渡されることを

期待しているかを指定する。それは二つの部分からなる。一つはthisポインタの有無と存在する場合の型

を扱い,もう一つは実引数を渡す機構に関連している。 

属性instanceが存在する場合,それはthisポインタがこのメソッドに渡されなければならないことを

示す。この属性はインスタンスメソッド及び仮想メソッドの両方に使われなければならない。 

通常,仮引数並び(これは常に呼出し規約に従う)は他の情報から導出可能であるため,thisポインタ

の型に関する情報を提供しない。しかし,instance explicitという組合せが指定される場合,後続す

る仮引数並びの最初の型はthisポインタの型を指定し,後続するエントリは仮引数の型自身を指定する。 

《呼出し種別》 ::= 

  default 

| unmanaged cdecl 

| unmanaged fastcall 

| unmanaged stdcall 

| unmanaged thiscall 

| vararg 

管理下コードは,呼出し種別default又はvarargだけをもつ。メソッドが任意個数の実引数を受理

する場合はvarargが使われなければならないが,これ以外のすべての場合にはdefaultを使用しなけ

ればならない。 

CLIの外側で実装されたメソッドを取り扱う場合,要求された呼出し規約を指定できることが重要とな

る。このため,呼出し種別の16通りの可能な符号化が存在する。そのうちの二つは管理下呼出し種別とし

て使われる。次の四つは多くのプラットフォーム間で定義された意味によって予約されている。 

− unmanaged cdeclは,標準のCで使われる呼出し規約とする。 

− unmanaged stdcallは,標準のC++呼出し規約を指定する。 

− unmanaged fastcallは,特殊な最適化C++の呼出し規約とする。 

− unmanaged thiscallは,メソッドに対しthisポインタを渡すC++の呼出しとする。 

更に四つが既存の呼出し規約のために予約されているが,これらの使用は移植性がない。更に四つが,

background image

182 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

将来の規格化のために予約されており,二つは,非標準の実験的な使用のために用いてもよい(ここでの

“移植性がある”とは,すべてのCLI規格適合処理系で利用可能であるという特徴を意味する。)。 

15.4 メソッドの定義 

《メソッドヘッダ》 ::= 

  《メソッド属性》* [《呼出し規約》 ] 《型》 

              [ marshal ʻ(ʼ [《プラットフォーム固有型》 ] ʻ)ʼ ]  
              《メソッド名》 [ ʻ<ʼ 《総称仮引数群》ʻ>ʼ ] ʻ(ʼ 《仮引数群》 ʻ)ʼ 《実装属性》* 

メソッドの先頭(箇条10参照)は次で構成する。 

− 呼出し規約(《呼出し規約》,15.3参照) 

− 任意個数の既定義メソッド属性(《メソッド属性》,15.4.2参照) 

− 省略可能な属性をもつ返却値の型 

− 省略可能な組換え情報(7.4参照) 

− メソッド名 

− 省略可能な総称仮引数(総称メソッドを定義する場合。10.1.7参照。) 

− 識別情報 

− 任意個数の実装属性(《実装属性》,15.4.3参照) 

返却値をもたないメソッドは,返却値の型としてvoidを用いなければならない。 

《メソッド名》 ::= 

  .cctor 

| .ctor 

| 《ドット名》 

メソッド名は,単純名か,又はインスタンス構成子及び型初期化子として用いられる特殊な名前のいず

れかとする。 

《仮引数群》 ::= [《仮引数》 [ ʻ,ʼ 《仮引数》]*  ] 

《仮引数》 ::= 

  ... 

| [《仮引数属性》* ] 《型》 [ marshal ʻ(ʼ [《プラットフォーム固有型》 ] ʻ)ʼ ] [《識別子》 ] 

《識別子》は,もしあれば仮引数の名前である。仮引数は,その名前を用いるか,又は仮引数のゼロか

ら始まる添字を用いるかのいずれかで参照することができる。CIL命令では,常にゼロから始まる添字を

用いて符号化される(名前はILAsmを使いやすくするために存在する。)。 

varargメソッドを呼び出す場合とは対照的に,varargメソッドの定義は省略記号(”…”)を含まな

いことに注意する。 

《仮引数属性》 ::= 

  ʻ[ʼ in ʻ]ʼ 

| ʻ[ʼ opt ʻ]ʼ 

| ʻ[ʼ out ʻ]ʼ 

仮引数属性は,仮引数に添付されなければならず(22.33参照),したがってメソッド識別情報の一部で

はない。 

注記 仮引数属性と異なり,カスタム修飾子(modopt及びmodreq)は,識別情報の一部である。

したがって,修飾子は,メソッド契約の一部をなすが,一方,仮引数属性はそうではない。 

in及びoutは,(管理下又は管理外の)ポインタ型の仮引数にだけ添付されてもよい。これらは,仮引

数がメソッドへの入力を提供すること,メソッドから値を返すこと,又はその両方を意図しているかどう

background image

183 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

かを指定する。いずれも指定されない場合,inが指定されたものと仮定される。CLI自体は,これらのビ

ットの意味を強制しないが,特に,メソッド呼出し元及びそのメソッドが異なるアプリケーション領域,

プロセッサ又はコンピュータに存在する場合,性能を最適化するためにそれらのビットを利用してもよい。 

optは,この仮引数がエンドユーザーの観点から省略可能であることを意図して指定する。供給される

値は,.param構文を用いて格納される(15.4.1.4参照)。 

15.4.1 メソッド本体 

メソッド本体は,プログラムの命令を含む。しかし,それはラベル,付加的な構文形式及びilasmに対

する付加的な情報を提供し,幾つかの言語でメソッドのコンパイルに有用な多くの指令を含んでもよい。 

《メソッド本体項目》 ::= 

記述 

箇条又は 
細分箇条 

  .custom 《カスタム宣言》 

カスタム属性の定義。 

21 

| .data 《データ宣言》 

データ節へのデータ出力。 

16.3 

| .emitbyte 《Int32》 

メソッドのコード節への符号なし1バイト出
力。 

15.4.1.1 

| .entrypoint 

このメソッドがアプリケーションに対する入
口点であることを指定する(そのようなメソ
ッドはただ一つだけ許される。)。 

15.4.1.2 

| .locals [ init ]  
  ʻ(ʼ 《局所変数識別情報》ʻ)ʼ 

このメソッドに対する局所変数を定義する。 15.4.1.3 

| .maxstack 《Int32》 

int32がメソッド実行中の評価スタックの最大
要素数を指定する。 

15.4.1 

| .override 《型指定》 ʻ::ʼ 《メソ
ッド名》 

現在のメソッドを指定されたメソッドの実装
として用いる。 

10.3.2 

| .override method 《呼出し規約》《型》
《型指定》 ʻ::ʼ 《メソッド名》《総称仮
引数数》ʻ(ʼ 《仮引数群》ʻ)ʼ 

現在のメソッドを指定されたメソッドの実装
として用いる。 

10.3.2 

| .param [《Int32》 ] [ ʻ=ʼ 《フィ
ールド初期値》 ] 

仮引数《Int32》に対して定数値《フィー

ルド初期値》を格納する。 

15.4.1.4 

| .param type ʻ[ʼ 《Int32》 ʻ]ʼ 

総称メソッドに型仮引数を指定する。 

15.4.1.5 

| 《外部ソース宣言》 

ソース行情報 

5.7 

| 《命令》 

命令。 

第4章 

| 《識別子》 ʻ:ʼ  

ラベル。 

5.4 

| 《有効範囲ブロック》 

局所変数の構文上の有効範囲。 

15.4.4 

| 《セキュリティ宣言》 

セキュリティ許可宣言 

20 

| 《構造化例外ブロック》 

例外ブロック。 

19 

15.4.1.1 .emitbyte指令 

《メソッド本体項目》 ::= …  

   | .emitbyte《Int32》 

この指令は,符号なし8ビット値をメソッドのCILストリーム中の本指令が出現する地点に直接出力さ

せる。 

注記 .emitbyte指令は,試験を生成するために用いる。通常のプログラム生成では用いない。 

15.4.1.2 .entrypoint指令 

《メソッド本体項目》 ::= …  

   | .entrypoint 

.entrypoint指令は,静的でなければならない現在のメソッドをアプリケーションの入口点として登

録する。VESはアプリケーションを開始するために,このメソッドを呼び出さなければならない。実行可

background image

184 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

能なプログラムは,ただ一つの入口点をもたなければならない。この入口点メソッドは,大域的メソッド

であるか,又は型の内側に現れてもよい(この指令の効果は,このメソッドに対するメタデータトークン

を,PEファイルのCLIヘッダ中に置くことにある。)。 

入口点メソッドは,一つも実引数を取ってはならないか,又は一つの文字列のベクトルを取らなければ

ならない。文字列のベクトルをとる場合,文字列は,実行形式への実引数を表現し,その第1実引数が添

字0によって表現される。これら実引数を指定する機構は,プラットフォーム依存であって,ここでは指

定されない。 

入口点メソッドの返却値の型は,void,int32又はunsigned int32のいずれかでなければならな

い。int32又はunsigned int32が返却される場合,その実行形式は,ホスト環境に対して終了コード

を返すことができる。値0は,そのアプリケーションが正常に終了したことを表す。 

入口点メソッドに対するアクセス制御は,実行開始時に,その使用することを妨げてはならない。一度

実行が開始されると,VESは入口点メソッドを他のメソッドと同等に扱う。 

例 次の例では第1実引数を印字し,オペレーティングシステムに正常に戻る。 

.method public static int32 MyEntry(string[] s) cil managed 

{ .entrypoint 

  .maxstack 2 

  ldarg.0  

// load and print the first argument 

  ldc.i4.0 

  ldelem.ref 

  call void [mscorlib]System.Console::WriteLine(string) 

  ldc.i4.0  

// return success 

  ret 

15.4.1.3 .locals指令 

.locals文は一つ以上の局所変数(第1章参照)を現在のメソッド用に宣言する。 

《メソッド本体項目》 ::= …  

   | .locals  [ init ] ʻ(ʼ 《局所変数識別情報》 ʻ)ʼ 

《局所変数識別情報》 ::= 《局所変数》 [ ʻ,ʼ 《局所変数》 ]* 

《局所変数》 ::= 《型》 [《識別子》 ] 

《識別子》は,もしあれば,対応する局所変数の名前とする。 

initが指定された場合,変数は,その型に対応する省略時の値で初期化される。すなわち,参照型は

nullで初期化され,値型はゼロで初期化される。 

注記 検証可能なメソッドは,initキーワードを含まなければならない(第3章参照)。 

例 

次の例では四つの局所変数を宣言しており,各々その省略時の値で初期化される。 

.locals init ( int32 i, int32 j, float32 f, int64[] vect) 

15.4.1.4 .param指令 

《メソッド本体項目》 ::= …  

   | .param ʻ[ʼ 《Int32》 ʻ]ʼ [ ʻ=ʼ 《フィールド初期値》 ] 

.paramは,メタデータにメソッド仮引数番号《Int32》で関連付けられた定数値を格納する(22.9参照)。

CLIは,仮引数用に値が供給されることを要請するが,一方ツールは,利用者ではなくツールに仮引数の

background image

185 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

値を供給することを意図して指定するために,この属性の存在を利用できる。CIL命令と異なり,.param

は,添字0をメソッドの返却値を指定するために,添字1をメソッドの第1仮引数を指定するために,添

字2をメソッドの第2仮引数を指定するために,以下同様に使用する。 

注記 CLIはこれらの値に対し,何ら意味的なものを付与しない。それは,(例えば省略時の実引数値

と呼ばれるような)任意の意味を実装するのは,完全にコンパイラ依存となる。 

15.4.1.5 .param type指令 

《メソッド本体項目》 ::= … 

   | .param typeʻ[ʼ 《Int32》 ʻ]ʼ 

本指令は,総称型又は総称メソッドに対する型仮引数を指定することを許可する。《Int32》は,この指

令を適用する型又はメソッドの仮引数の1から始まる序数とする。 

注記 本指令は.custom指令との組み合せで用い,カスタム属性と型仮引数を結びつける。 

.param type指令がクラスの有効範囲で用いられた場合,そのクラスの型仮引数を参照する。この指

令がクラス定義内のメソッド有効範囲で用いられた場合,そのメソッドの型仮引数を参照する。これら以

外でこの指令が現れた場合,プログラムは,不適格とする。 

例 

.class public G<T,U> { 

  .param type [1]  

// refers to T 

  .custom instance void TypeParamAttribute::.ctor() = (01 00 ... ) 

  .method public void Foo<M>(!!0 m) { 

     .param type [1] 

// refers to M 

     .custom instance void AnotherTypeParamAttribute::.ctor() = (01 

00 ... ) 

      … 

  } 

  … 

15.4.2 メソッドに対する既定義の属性 

《メソッド属性》 ::= 

記述 

細分箇条 

  abstract 

メソッドは抽象とする(かつ,仮想的でなけ
ればならない。)。 

15.4.2.4 

| assembly 

アセンブリアクセス可能性。 

15.4.2.1 

| compilercontrolled 

コンパイラ制御アクセス可能性。 

15.4.2.1 

| famandassem 

ファミリ及びアセンブリアクセス可能性。 

15.4.2.1 

| family 

ファミリアクセス可能性。 

15.4.2.1 

| famorassem 

ファミリ又はアセンブリアクセス可能性。 

15.4.2.1 

| final 

本仮想メソッドは,派生クラスによって上書
きされない。 

15.4.2.2 

| hidebysig 

識別情報による隠ぺい。実行時には無視され
る。 

15.4.2.2 

| newslot 

本メソッドには仮想メソッド表上で新しいス
ロットを割り当てなければならないことを指
定する。 

15.4.2.3 

background image

186 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

《メソッド属性》 ::= 

記述 

細分箇条 

| pinvokeimpl ʻ(ʼ 
    《引用文字列》 [ as 《引用文字列》 ] 
    《PInvoke属性》* ʻ)ʼ 

メソッドが実際には,基礎とするプラットフ
ォーム上でプラットフォーム固有のコードで
実装されている。 

15.4.2.5 

| private 

非公開アクセス可能性。 

15.4.2.1 

| public 

公開アクセス可能性。 

15.4.2.1 

| rtspecialname 

メソッド名が実行時システムでは特別に取り
扱われる必要がある。 

15.4.2.6 

| specialname 

メソッド名は,ツールによっては特別に取り
扱われる必要がある。 

15.4.2.6 

| static 

メソッドは静的とする。 

15.4.2.2 

| virtual 

メソッドは仮想的とする。 

15.4.2.2 

| strict 

上書きに関するアクセス有効性を検査する。 

15.4.2.2 

既定義の属性に対する次の組合せは,不当とする。 

− staticをfinal,newslot又はvirtualのいずれかと組み合わせる。 

− abstractをfinal又はpinvokeimplのいずれかと組み合わせる。 

− compilercontrolledをfinal,rtspecialname,specialname又はvirtualのいずれかと

組み合わせる。 

15.4.2.1 アクセス可能性情報 

《メソッド属性》::= … 

| assembly 
| compilercontrolled 
| famandassem 
| family 
| famorassem 
| private 
| public 

これら属性のうち一つだけをメソッドに与える(第1章参照)。 

15.4.2.2 メソッド契約属性 

《メソッド属性》 ::= … 

| final 
| hidebysig 
| static 
| virtual 
| strict 

これらの属性は,組み合わせることができる。ただし,メソッドは,static,かつ,virtualであっ

てはならない。virtualメソッドだけがstrict又はfinalとならなければならない。さらに,抽象メ

ソッドは,finalであってはならない。 

finalメソッドは,この型の派生クラスによって上書きされてはならない。 

hydebysigは,ツールが使用するためのものであり,VESでは無視される。それは宣言されたメソッ

ドが,対応するメソッド識別情報をもつ基底型のすべてのメソッドを隠ぺいすることを指定する。省略さ

れた場合,メソッドは,識別情報にかかわらず,同じ名前をもつすべてのメソッドを隠ぺいする。 

根拠: 名前による隠ぺいによって意味づけを与える(C++のような)言語もあるが,一方(C#やJava™ 

のように)名前と識別情報による隠ぺいによって意味づけを与える言語もある。 

static及びvirtualについては,15.2を参照。 

background image

187 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

strict virtualメソッドは,それらがアクセス可能である場合に限り上書きすることができる。

23.1.10参照。 

15.4.2.3 上書きの動作 

《メソッド属性》 ::= … 
   | newslot 

newslotは,virtualメソッドと一緒にだけ使用することができる(10.3参照)。 

15.4.2.4 メソッド属性 

《メソッド属性》 ::= … 

   | abstract 

abstractは,final指定のないvirtualメソッドでだけ使われなければならない。それは,メソッ

ドの実装がここでは提供されず,しかし派生クラスで提供されなければならないことを指示する。

abstractメソッドは,抽象型においてだけ出現しなければならない(10.1.4参照)。 

15.4.2.5 相互運用属性 

《メソッド属性》 ::= …  

   | pinvokeimpl ʻ(ʼ 《引用文字列》 [ as 《引用文字列》 ] 《PInvoke属性》* ʻ)ʼ 

15.5.2及び25.20を参照する。 

15.4.2.6 特別な処理属性 

《メソッド属性》 ::= … 

   | rtspecialname 
   | specialname 

属性rtspecialnameは,メソッド名が実行時システムに対して特別に取り扱われなければならないこ

とを指定する。特別な名前の例としては,.ctor(オブジェクト構成子)及び.cctor(型初期化子)が

ある。 

specialnameは,このメソッドの名前が,ツールによっては特別な意味をもつことを指定する。 

15.4.3 メソッドの実装属性 

《実装属性》 ::= 

記述 

細分箇条 

  cil 

メソッドは標準CILコードを含んでいる。 15.4.3.1 

| forwardref 

本メソッドの本体は,ここでの宣言では指
定されない。 

15.4.3.3 

| internalcall 

メソッド本体はCLI自身によって提供さ
れることを表す。 

15.4.3.3 

| managed 

メソッドは管理下メソッドである。 

15.4.3.2 

| native 

メソッドはプラットフォーム固有のコー
ドを含む。 

15.4.3.1 

| noinlining 

実行時システムは,メソッドのインライン
展開を禁止する。 

15.4.3.3 

| runtime 

メソッドの本体は定義されていないが,実
行時に生成される。 

15.4.3.1 

| synchronized 

メソッドは,単一スレッド方式で実行され
なければならない。 

15.4.3.3 

| unmanaged 

メソッドが管理外であることを指定する。 15.4.3.2 

15.4.3.1 コード実装属性 

《実装属性》 ::= 

   | cil 
   | native 

background image

188 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

   | runtime 

これらの属性は相互に排他的とする。これらはメソッドに含まれるコードの型を指定する。 

cilは,メソッド本体がcilコードで構成されていることを表す。メソッドがabstract宣言されて

いる場合を除き,メソッドの本体は,cilが使われている場合,それが提供されなければならない。 

nativeは,メソッドがコードが生成された特定のプロセッサに依存したプラットフォーム固有のコー

ドで実装されることを指定する。nativeメソッドは,本体をもってはならないが,代わりに本体を宣言

するプラットフォーム固有のメソッドを参照する。典型的には,CLIのPInvoke機能(15.5.2参照)が,プ

ラットフォーム固有のメソッドを参照するために用いられる。 

runtimeは,メソッドの実装が実行時に実行時システムによって自動的に供給され,基本的には委譲

(14.6参照)のメソッド用に用いられる。 

15.4.3.2 管理下又は管理外 

《実装属性》 ::= 

   | managed 
   | unmanaged 

これらは,組み合わせてはならない。CILを用いて実装されたメソッドは,manegedとする。unmanaged

は,基本的にPInvokeと一緒に用いる(15.5.2参照)。 

15.4.3.3 実装情報 

《実装属性》 ::= 

   | forwardref 
   | internalcall 
   | noinlining  
   | synchronized 

これらの属性は組み合わせることができる。 

forwardrefは,メソッドの本体がどこか別の場所で提供されることを指定する。この属性はVESに

よってアセンブリがロードされる場合には,存在してはならない。これは,(静的リンカのような)ツール

が,分割してコンパイルされたモジュールに対する前方参照を解決するために用いられる。 

internalcallは,メソッド本体がこのCLI規格によって提供されることを指定する(さらに,典型

的にはシステムライブラリ中の低水準メソッドによって用いられる。)。それは,CLIの実装をまたぐ利用

を意図したメソッドに適用してはならない。 

noinliningは,このメソッドの本体がCILからプラットフォーム固有へのコンパイラによって,任意

の呼出し元メソッドに含まれてはならないことを指定する。それは分離したルーチンとして保持されなけ

ればならない。 

注記 根拠は次のとおりである。メソッドがインライン化されないことを指定することで,デバッグ

(例えばスタックトレースの表示)及びプロファイル時にメソッドが可視のままとなる。それ

はまた,CILからプラットフォーム固有コードへのコンパイラがインライン化に用いる省略時

の発見的手法をプログラマが上書きする機構を与える。 

synchronizedは,メソッドの全本体が,単一スレッドによるものでなければならないことを指定する。

もし,このメソッドがインスタンスメソッド又は仮想メソッドである場合は,メソッドに入る前にオブジ

ェクトのロックを取得しなければならない。メソッドが静的メソッドである場合は,メソッドに入る前に

その閉型のロックを取得しなければならない。もしロックを取得できなかった場合,ロックが許可される

まで,要求しているスレッドの実行を進めてはならない。これはデッドロックの原因となり得る。通常の

background image

189 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

戻り又は例外のいずれかによってメソッドから出るとロックは開放される。同期されたメソッドのtail.

呼出しを用いた終了は,tail.が指定されなかったかのように実装されなければならない。noinlining

は,実行時システムがこのメソッドをインライン化してはならないことを指定する。インライン化とは,

call命令を呼び出されるメソッドの本体で置き換える処理をいう。これは実行時システムによって最適

化を目的として行われてもよい。 

15.4.4 有効範囲ブロック 

    《有効範囲ブロック》 ::= ʻ{ʼ 《メソッド本体項目》* ʻ}ʼ 

《有効範囲ブロック》は,メソッド本体の要素をまとめてグループ化するために用いられる。例えば,

それは,例外ハンドラの本体を構成するコード列を指し示すために使われる。 

15.4.5 varargメソッド 

varargメソッドは,可変個数の実引数を受理する。これらは,varargの呼出し規約を用いなければ

ならない(15.3参照)。 

各呼出し元において,メソッド参照は,渡される固定及び可変の実引数の型を記述するために用いられ

なければならない。実引数並びのうち固定部分は,省略記号で表される付加的な実引数と区別されなけれ

ばならない(第1章参照)。 

注記 メソッド参照はMethodRef(22.25参照)又はMethodDef(22.26参照)のいずれかによって

表される。MethodRefは,そのメソッドが同じアセンブリで定義されたときにも必要となる

ことがある。なぜならばMethodDefは,実引数並びの固定部分だけを記述するためである。呼

出し側が付加的な実引数を渡さない場合,同じアセンブリで定義されたvarargメソッドに対

しMethodDefを用いることができる。 

vararg実引数は,CIL命令arglistを用いて実引数並びのハンドルを得ることによってアクセスされ

なければならない(第3章参照)。そのハンドルは,実引数にアクセスするための型安全な機構を提供す

る値型System.ArgIteratorのインスタンスを生成するために使われる(第4章参照)。 

例 次の例では,varargメソッドがどのように宣言され,第1vararg実引数にどのようにアクセス

するかを示している。 

なお,少なくとも一つの付加的な実引数がメソッドに対し渡されることを仮定している。 

.method public static vararg void MyMethod(int32 required) { 

  .maxstack 3 

  .locals init (valuetype [mscorlib]System.ArgIterator it, int32 x) 

  ldloca it 

// initialize the iterator 

  initobj  valuetype [mscorlib]System.ArgIterator 

  ldloca it 

  arglist  

// obtain the argument handle 

  call 

instance void 

[mscorlib]System.ArgIterator::.ctor(valuetype  

     [mscorlib]System.RuntimeArgumentHandle) // call constructor of 

iterator 

  /* argument value will be stored in x when retrieved, so load 

   address of x */ 

background image

190 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

  ldloca x 

  ldloca it 

  // retrieve the argument, the argument for required does not matter 

  call 

instance typedref 

[mscorlib]System.ArgIterator::GetNextArg() 

  call 

object 

[mscorlib]System.TypedReference::ToObject(typedref) /* retrieve the 

     object */ 

  castclass [mscorlib]System.Int32 

// cast and unbox 

  unbox 

int32 

  cpobj 

int32  

// copy the value into x 

  // first vararg argument is stored in x 

  ret 

15.5 管理外メソッド 

管理下コード及び管理下データの提供に加えて,CLIは管理外コードという,基礎とするプラットフォ

ームにおける既存のプラットフォーム固有のコードにアクセスするための便宜を提供する。これらの便宜

は,必要上,プラットフォーム依存であり,したがってここでは部分的にだけ規定する。 

この規格では次を規定する。 

− 管理外コードから呼び出される管理下コードへの関数ポインタを提供するためのファイルフォーマッ

ト中の機構(15.5.1参照)。 

− 管理外コード内で実装されているとして,特定のメソッド定義を印付けるための機構(プラットフォ

ーム呼出しと呼ばれる。15.5.2参照)。 

− 管理外メソッドへの呼出しであることを示すため,メソッドポインタを用いた呼出し元を印付けるた

めの機構(15.5.3参照)。 

− CLIのすべての実装上で,上の機構を用いて渡される(組み換えられる)既定義データ型の小さな集

合(15.5.4参照)。その型の集合は,カスタム属性及びカスタム修飾子の使用を通じて拡張することが

できる。ただし,これらの拡張はプラットフォーム依存となる。 

15.5.1 メソッド遷移仲介コード 

注記 この機構は,カーネルプロファイルの一部ではないため,CLI規格適合処理系のすべてには存

在しなくてもよい(第4章参照)。 

管理外コードから管理下コードを呼び出すために,プラットフォームによっては特定の遷移列を実行す

る必要がある。さらに,プラットフォームによっては,データ型の表現を変換する必要がある(データ組

換え。)。これらの問題はともに.vtfixup指令によって解決される。この指令は,複数回出現することが

できるが,次の文法で示されるとおりCILアセンブリファイルの最上位だけとする。 

《宣言》::= 

細分箇条 

  .vtfixup《vtfixup宣言》 

| … 

5.10 

.vtfixup指令は,特定のメモリ位置にメソッドポインタに変換されなければならないメソッドを参照

するメタデータトークンを含む表が存在することを宣言する。CLIは,.vtfixup指令を含むファイルが

background image

191 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

実行時にメモリ中にロードされると,自動的にこの変換を行う。その宣言は,表中の入口数,要求される

メソッドポインタの種別,表中の入口の大きさ及び表の位置を指定する。 

《vtfixup宣言》::= 

  [《Int32》 ] 《vtfixup属性》* at 《データラベル》 

《vtfixup属性》::= 

 Fromunmanaged 
| int32 
| int64 

属性int32及びint64は,相互に排他的であり,省略時はint32が想定される。これらの属性は,表

の各スロットの大きさを指定する。各スロットは,32ビットのメタデータトークン(表が64ビットスロ

ットである場合はゼロが詰められる。)を含み,CLIはそれを,スロットと同じ大きさをもつメソッドポイ

ンタに変換する。 

fromunmanagedが指定された場合,CLIは仲介コードを生成する。ここで仲介コードとは,管理外メ

ソッド呼出しを管理下呼出しに変換し,メソッドを呼び出し,更に,管理外環境へ結果を返すものである。

仲介コードはまた,プラットフォーム呼出しで記述された,プラットフォーム依存の様式でデータ組換え

を実行する。 

ILAsm構文は,トークンの表を生成する機構を規定しないが,しかしコンパイラは,.data指令を用い

て指定されたブロックに,単にバイトリテラルとしてトークンを生成することができる。 

15.5.2 プラットフォーム呼出し 

プラットフォーム固有のコードで定義されたメソッドは,CLIにおけるプラットフォーム呼出し

(PInvoke又はp/invokeとしても知られている。)機能を用いて呼び出すことができる。プラットフォーム

呼出しは,管理下から管理外へ,及びその逆へ切り替え,更に,必要なデータ組換えの処理を行う。PInvoke

を用いて呼び出される必要があるメソッドは,pinvokeimplで印付けられる。加えて,メソッドは実装

属性native及びunmanagedをもたなければならない(15.4.2.4参照)。 

《メソッド属性》::= 

記述 

細分箇条 

  pinvokeimpl ʻ(ʼ 《引用文字列》 [ as 《引用文字
列》 ] 《PInvoke属性》* ʻ)ʼ 

プラットフォーム固有のコードにて
実装される。 

| … 

15.4.2.5  

最初の引用文字列は,プラットフォーム依存の記述であって,メソッドの実装が配置される場所を表す

(例えば,Microsoft Windows™では,ここは,メソッドを実装するDLLの名前である)。第2の(省略可

能な)引用文字列は,該当するプラットフォーム上に存在するメソッドの名前である。プラットフォーム

上では,管理下プログラム上に出現する名前を,プラットフォーム固有の実装に現れる名前と異なる名前

にする名前変換規則を用いることができるので,この第2の引用文字列を用意している(例えば,C++コ

ンパイラによって生成されたプラットフォーム固有のコードである場合,この規則は一般的である)。 

大域的有効範囲(すなわち,任意の型の外側)で定義された,静的メソッドだけが,pinvokeimplで

印付けることができる。pinvokeimpl付きで宣言されたメソッドは,定義の一部として指定される本体

をもってはならない。 

《PInvoke属性》::= 

記述(プラットフォーム依存であり,提案だけ。) 

  ansi 

ANSI文字集合。 

| autochar 

文字集合を自動的に決定する。 

| cdecl 

標準C言語形式の呼出し。 

background image

192 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

| fastcall 

C言語形式のfastcall。 

| stdcall 

標準C++言語形式の呼出し。 

| thiscall 

メソッドが暗黙のthisポインタを受理する。 

| unicode 

Unicode文字集合。 

| platformapi 

対象となるプラットフォーム上で適切な呼出し
規約を用いる。 

属性ansi,autochar,及びunicodeは,相互に排他的とする。これらは,thisメソッドの呼出し

に対して,文字列がどのように組み換えられるかを管理する。ansiは,プラットフォーム固有のコード

がANSI文字集合で符号化された文字列に対応するプラットフォーム依存の表現を受理する(及び場合に

よっては返却する。)ことを表す(これはC言語又はC++言語の文字列定数の表現に一致する。)。autochar

は,基礎とするプラットフォーム上で,“自然な”プラットフォーム依存の表現を表す。unicodeは,そ

のプラットフォーム上でUnicodeメソッドを用いるために符号化された文字列に対応する,プラットフ

ォーム依存の表現を表す。 

属性cdecl,fastcall,stdcall,thiscall,及びplatformapiは,相互に排他的である。これ

らはプラットフォーム依存であり,かつ,プラットフォーム固有のコード用の呼出し規約を指定する。 

例 次の例では,Microsoft Windows™ DLL user32.dllに置かれているメソッドMessageBeepの宣言

を示している。 

.method public static pinvokeimpl("user32.dll" stdcall) int8 

      MessageBeep(unsigned int32) native unmanaged {} 

15.5.3 関数ポインタを通じてのメソッド呼出し 

管理外メソッドは,関数ポインタを通じて呼び出すこともできる。管理下メソッド又は管理外メソッド

をポインタを用いて呼び出すことに関しての差異はない。しかし,管理外メソッドは,15.5.2で述べられ

たとおりpinvokeimpl付きで宣言される必要がある。管理下メソッドを関数ポインタを用いて呼び出す

ことについては,14.5に示す。 

15.5.4 データ型組換え 

データ型組換えは,必要上プラットフォーム依存とするが,この規格はCLI規格適合処理系が提供しな

ければならないデータ型の最小限の集合を規定する。付加的なデータ型を,プラットフォーム依存の様式

で提供してもよい。 

次のデータ型は,すべてのCLI規格適合処理系で組み換えられなければならない。それらがどのプラッ

トフォーム固有のデータ型に適合するかは,プラットフォーム規定とする。 

− native整数型を含むすべての整数データ型(int8,int16,unsigned int8,bool,charほか)。 

− 基礎とするデータ型としての列挙。 

− すべての浮動小数点データ型(floar32及びfloat64),ただしそれらが管理下コード用にCLI実装

として提供されている場合。 

− string型。 

− 上の任意の型への管理外ポインタ。 

上に加え,次の型が管理下コードから管理外コードへの組換え用に提供されなければならない。しかし,

逆方向(すなわち,管理外メソッドを呼び出す場合の返却値の型として,又は管理外メソッドから管理下

メソッドを呼び出す場合の仮引数として)については提供する必要はない。 

− 上の任意の型の添字がゼロから始まる1次元配列 

− 委譲(管理外コードから委譲を呼び出す機構はプラットフォーム規定とする。委譲の組換えが,管理

background image

193 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

外コードから直接利用可能な関数ポインタを生成することを仮定してはならない。)。 

最後に,型system.Runtime.InteropServices.GCHandleは,オブジェクトを管理外コードに組

み換えるために用いてもよい。その管理外コードは,特定のオブジェクトに対する”不透明のハンドル”と

して利用可能な,プラットフォーム依存のデータ型を受理する(第4章参照)。 

16 フィールドの定義及び参照 

フィールドは,プログラムのデータを格納する型付きのメモリ領域とする。CLIでは,インスタンスフ

ィールド及び静的フィールドの両方の宣言が可能とする。静的フィールドは,型と関連付けられ,その型

のすべてのインスタンスを共有しているのに対し,インスタンスフィールドは,その型の特定のインスタ

ンスに関連付けられている。インスタンス化されるとインスタンスは,各インスタンスフィールドに対す

る固有のコピーをもつ。 

CLIは,大域的なフィールド,すなわち,任意の型定義の外側で宣言されたフィールドも提供する。大

域的なフィールドは静的でなければならない。 

フィールドは,.field指令によって定義される(22.15参照)。 

《フィールド》 ::= .field 《フィールド宣言》 

《フィールド宣言》 ::= 

[ ʻ[ʼ 《Int32》 ʻ]ʼ ] 《フィールド属性》* 《型》《識別子》 [ ʻ=ʼ 《フィールド初期値》 | at 《デ
ータラベル》 ] 

《フィールド宣言》は,次の部分をもつ。 

− 省略可能な整数値。インスタンス内でのフィールドのバイトオフセットを指定する(10.7参照)。この

値が存在する場合,このフィールドを含む型は,配置属性explicitをもたなければならない。オフ

セットは,大域的フィールド又は静的フィールドでは与えられてはならない。 

− 任意個数のフィールド属性(16.2参照)。 

− 型。 

− 名前。 

− 省略可能な《フィールド初期値》節(16.2参照)又は《データラベル》節(5.4参照)のいずれか。 

大域的フィールドは,それと関連付けられたデータラベルをもたなければならない。これは,PEファイ

ル中のどこに,そのフィールドのデータが位置するのかを指定する。型の静的フィールドには,必す(須)

ではないが,データラベルが割り当てられてもよい。 

例  

.field private class [.module Counter.dll]Counter counter 

.field public static initonly int32 pointCount 

.field private int32 xOrigin 

.field public static int32 count at D̲0001B040 

16.1 フィールドの属性 

フィールドの属性は,アクセス可能性に関する情報,契約情報,相互操作属性,特別な処理に関する情

報などを指定する。 

次の細分箇条は,フィールドの既定義属性の各グループにおける付加情報を含む。 

《フィールド属性》::= 

記述 

細分箇条 

  assembly 

アセンブリアクセス可能性。 

16.1.1 

background image

194 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

《フィールド属性》::= 

記述 

細分箇条 

| famandassem 

ファミリ及びアセンブリアクセス可能性。 

16.1.1 

| family 

ファミリアクセス可能性。 

16.1.1 

| famorassem 

ファミリ又はアセンブリアクセス可能性。 

16.1.1 

| initonly 

定数フィールドを印付ける。 

16.1.2 

| literal 

メタデータフィールドを指定する。このフィール
ドには実行時にメモリは割り当てられない。 

16.1.2 

| marshal ʻ(ʼ 《プラットフォーム
固有型》 ʻ)ʼ 

組換え情報。 

16.1.3 

| notserialized 

予約済み(このフィールドは,直列化されないこ
とを表す。)。 

16.1.2 

| private 

非公開アクセス可能性。 

16.1.1 

| compilercontrolled 

コンパイラ制御アクセス可能性。 

16.1.1 

| public 

公開アクセス可能性。 

16.1.1 

| rtspecialname 

実行時の特別な取扱い。 

16.1.4 

| specialname 

別のツールによる特別な名前。 

16.1.4 

| static 

静的なフィールド。 

16.1.2 

16.1.1 アクセス可能性情報 

アクセス可能性属性には,assembly,famandassem,family,famorassem,private,

compilercontrolled,及びpublicがある。これらの属性は相互に排他的とする。 

アクセス可能性属性については,8.2で規定する。 

16.1.2 フィールド契約属性 

フィールド契約属性には,initonly,literal,static,及びnotserializedがある。これらの

属性は組み合わせることができる。しかし,staticフィールドだけがliteralでなければならない。

省略時は,直列化可能なインスタンスフィールドとなる。 

staticは,フィールドが,型のインスタンスではなく,型自身と関連付けられていることを指定する。

静的なフィールドへは,型のインスタンスをもつことなしに,例えば静的なメソッドによってアクセスす

ることができる。結論として,アプリケーション領域において,静的フィールドは型のすべてのインスタ

ンス間で共有されているため,このフィールドの任意の変更は,すべてのインスタンスに影響を及ぼす。

staticが指定されない場合,インスタンスフィールドが生成される。 

initonlyは,定数フィールドに対し,それらが初期化された後に印をつける。これらのフィールドは,

構築子の中でだけ変更できる。フィールドが静的フィールドである場合,それが宣言された型の初期化子

の中でだけ変更できる。インスタンスフィールドである場合,それが定義された型のインスタンス構築子

のうちの一つにおいてだけ変更できる。 

注記 initonlyフィールドにおけるldflda又はldsfldaの使用は,コードを正当性検証不能と

する。正当性検証不能コードでは,VESはinitonlyフィールドが構築子の外側で変更された

かどうかを検査する必要がない。VESは,メソッドが定数の値を変更しても何らエラーを報告

する必要がない。しかし,そのようなコードは妥当ではない。 

literalは,このフィールドが定数値を表すことを指定する。このようなフィールドには値を割り当て

なければならない。initonlyフィールドと異なり,literalフィールドは実行時には存在しない。それ

らに対してメモリは割り当てられない。literalフィールドは,メタデータの一部とはなるが,コードか

らアクセスすることはできない。literalフィールドには《フィールド初期値》構文を用いて値が割り当

てられる(16.2参照)。 

background image

195 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

注記 リテラルを参照するソースコードを実際の値への参照に置き換えることは,CILを生成するツ

ールが担当して行う。したがって,リテラルの値を変更すると,そのリテラルを参照している

任意のコードを再コンパイルする必要がある。このためリテラル値は,ソフトウェアバージョ

ン非互換となる。 

16.1.3 相互操作属性 

既存のプラットフォーム固有のアプリケーションとの相互操作のための属性が一つ用意されている。こ

れはプラットフォーム依存であり,CLIの複数の実装で動作させることを意図したコードでは用いてはな

らない。その属性はmarshalであり,フィールド定数が管理外コードに渡される場合,指定されたプラ

ットフォーム固有のデータ型との間で相互変換を行うことを指定する。すべてのCLI規格適合処理系は,

省略時の組換え規則をもつと同時にmarshal属性を用いて指定された自動変換に関する制約ももつ

(15.5.4参照)。 

注記 利用者定義の型に対する組換えは,CLIのすべての実装に対して要求されるものではない。こ

の規格では,それを提供する実装が一貫した動作で制御を行うように規定されている。これは,

この機能を用いたコードの可搬性を保証するには十分ではないが,そのようなコードが可搬と

なる可能性は高くなる。 

16.1.4 その他の属性 

属性rtspecialnameは,フィールド名が実行時に特別な方法で取り扱われなければならないことを表

す。 

注記 根拠は次のとおりである。現時点でrtspecialnameで印付けが必要なフィールド名は存在し

ない。これは拡張,将来の規格,及びフィールド宣言とメソッド宣言との間の一貫性を増加さ

せるために提供されている(インスタンスメソッド及び型初期化子メソッドは,本属性で印付

けられなければならない。)。 

属性specialnameは,フィールド名が実行環境以外のツールに対して特別な意味をもつことを表す。

典型的にはCLSに対して意味のある名前として印付けるために存在する(第1章参照)。 

16.2 フィールド初期化メタデータ 

《フィールド初期値》メタデータは,省略可能であり,フィールド宣言に付加することができる。本機

能は,データラベルと組み合わせて用いてはならない。 

《フィールド初期値》情報はメタデータに格納され,この情報はメタデータから問い合わせることがで

きる。しかしCLIは,対応するフィールドを自動的に初期化するためにこの情報を利用するのではない。

フィールド初期化子は,literalフィールド(16.1.2参照)又は省略時の値をもつ仮引数において典型的

に利用されている(22.9参照)。 

次の表は,フィールド初期化子用の選択肢を一覧している。型及びフィールド初期化子の両方が,メタ

データに格納されるが,それらが一致するという要求はないことに注意する(任意の移入コンパイラは,

格納された値を対象となるフィールド型に強制型変換する責任を負う。)。次の表の記述欄に,付加情報を

提供する。 

《フィールド初期値》 ::= 

記述 

  bool ʻ(ʼ true | false ʻ)ʼ 

真理値,true又はfalseでコード化される。 

| bytearray ʻ(ʼ 《バイト列》 ʻ)ʼ 

バイト列,型変換なしで格納される。合計バイト数が偶
数となるよう1バイトのゼロが詰められることがある。 

| char ʻ(ʼ 《Int32》 ʻ)ʼ 

16ビット符号なし整数(unicode文字)。 

background image

196 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

| float32 ʻ(ʼ 《Float64》 ʻ)ʼ 

32ビット浮動小数点数,浮動小数点数が括弧内に指定さ
れる。 

| float32 ʻ(ʼ 《Int32》 ʻ)ʼ 

《Int32》は,浮動小数点数のバイナリ表現である。 

| float64 ʻ(ʼ 《Float64》 ʻ)ʼ 

64ビット浮動小数点数,浮動小数点数が括弧内に指定さ
れる。 

| float64 ʻ(ʼ 《Int64》 ʻ)ʼ 

《Int64》は,倍精度浮動小数点数のバイナリ表現である。 

| [ unsigned ] int8 ʻ(ʼ 《Int32》 ʻ)ʼ 

8ビット整数,括弧内に整数が指定される。 

| [ unsigned ] int16 ʻ(ʼ 《Int32》 ʻ)ʼ 

16ビット整数,括弧内に整数が指定される。 

| [ unsigned ] int32 ʻ(ʼ 《Int32》 ʻ)ʼ 

32ビット整数,括弧内に整数が指定される。 

| [ unsigned ] int64 ʻ(ʼ 《Int32》 ʻ)ʼ 

64ビット整数,括弧内に整数が指定される。 

| 《引用文字列》 

文字列。《引用文字列》はUnicodeで格納される。 

| nullref 

空オブジェクト参照。 

例 次の例は,この典型的な利用を示す。 

.field public static literal valuetype ErrorCodes no̲error = int8(0) 

フィールド名no̲errorは,型ErrorCodes(値型)をもつリテラルであり,そのためのメ

モリは確保されない。ツール及びコンパイラは,値を走査し,それが値0をもつ8ビット符号付

き整数であることを検出できる。 

16.3 PEファイル中の埋込みデータ 

PEファイル中に格納されたデータフィールドを宣言する,幾つかの方法がある。すべての場合につい

て,.data指令が使用される。データは,最上位で.data指令を用いることでPEファイルに埋め込むこと

ができる。 

《宣言》::= 

細分箇条 

  .data 《データ宣言》 

| … 

6.6 

データは,型の一部として宣言することもできる。 

《クラスメンバ》 ::= 

細分箇条 

  .data 《データ宣言》 

| … 

10.2 

さらに,もう一つの選択肢として,メソッドの内側にデータを宣言する方法がある。 

《メソッド本体項目》 ::= 

細分箇条 

  .data 《データ宣言》 

| … 

15.4.1 

16.3.1 データ宣言 

.data指令は,省略可能なデータラベル及び実際のデータを定義する本体を含む。データラベルは,コ

ードからデータをアクセスしようとする場合に用いる。 

《データ宣言》 ::= [《データラベル》 ʻ=ʼ ] 《データ本体》 

本体は,一つのデータ項目又はデータ項目の並びを中括弧でくくったもののいずれかとする。データ項

目の並びは,配列と同様とする。 

《データ本体》 ::= 

  《データ項目》 

| ʻ{ʼ 《データ項目並び》 ʻ}ʼ 

項目の並びは,任意個数の項目からなる。 

《データ項目並び》 ::= 《データ項目》 [ ʻ,ʼ《データ項目並び》] 

データ項目の並びは,一つのラベルに関連付けられた複数のデータ項目を宣言するために用いてもよい。

background image

197 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

データ項目は,宣言された順に配置される。最初のデータ項目は,ラベルを通して直接アクセス可能であ

る。その他の項目にアクセスするには,ポインタ算術を用いる。すなわち,各データ項目の大きさを加え

ることで,並び内の次の項目を得ることができる。ポインタ算術の利用は,アプリケーションを正当性検

証不能とする(各データ項目は,後に参照されることがあれば,《データラベル》をもたなければならない。

《データラベル》の欠落は,データ項目の間に境界調整用の詰め物を挿入する目的で有用となる。)。 

データ項目は,データの型を宣言し,かつ,括弧内でデータを提供する。データ項目の並びが,同じ型

の項目及び初期値を含む場合,次の文法が,幾つかの型に対する短縮形として用いることができる。項目

が繰り返される個数は,宣言の後で大括弧内に置く。 

《データ項目》 ::= 

記述 

  ʻ&ʼ ʻ(ʼ 《識別子》 ʻ)ʼ 

ラベルのアドレス 

| bytearray ʻ(ʼ 《バイト列》 ʻ)ʼ 

バイトの配列 

| char ʻ*ʼ ʻ(ʼ 《引用文字列》 ʻ)ʼ 

Unicode文字の配列 

| float32 [ ʻ(ʼ 《Float64》 ʻ)ʼ ] [ ʻ[ʼ 《Int32》 
ʻ]ʼ ] 

32ビット浮動小数点数,繰り返してもよい。 

| float64 [ ʻ(ʼ 《Float64》 ʻ)ʼ ] [ ʻ[ʼ 《Int32》 
ʻ]ʼ ] 

64ビット浮動小数点数,繰り返してもよい。 

| int8 [ ʻ(ʼ 《Int32》 ʻ)ʼ ] [ʻ[ʼ 《Int32》 ʻ]ʼ ] 8ビット整数,繰り返してもよい。 
| int16 [ ʻ(ʼ 《Int32》> ʻ)ʼ ] [ ʻ[ʼ 《Int32》 
ʻ]ʼ ] 

16ビット整数,繰り返してもよい。 

| int32 [ ʻ(ʼ 《Int32》 ʻ)ʼ ] [ʻ[ʼ 《Int32》 ʻ]ʼ ] 32ビット整数,繰り返してもよい。 
| int64 [ ʻ(ʼ 《Int64》ʻ)ʼ ] [ ʻ[ʼ 《Int32》 ʻ]ʼ ] 64ビット整数,繰り返してもよい。 

例 

次の例では,値123をもつ32ビット符号付整数を宣言している。 

.data theInt = int32(123) 

次の例では,値3をもつ8ビット整数の10個の複製を宣言する。 

.data theBytes = int8 (3) [10] 

16.3.2 PEファイルからのデータへのアクセス 

.data指令を用いてPEファイルに格納されたデータは,静的変数を通してアクセスすることができる。

ここで静的変数は,大域的であっても,データの特定の位置で宣言された型のメンバであってもよい。 

《フィールド宣言》 ::= 《フィールド属性》* 《型》《識別子》 at 《データラベル》 

データは,その他の静的変数にアクセスするかのように,ldsfld,ldsfldaなどの命令を用いて,プ

ログラムからアクセスされる(第3章参照)。 

PEファイル内から,データにアクセスする方法は,プラットフォーム依存の規則に従う。典型的には,

PEファイル形式自身の中で,セクションにアクセスする場合の許可と関連している。 

例 次の例では,16.3.1の例で宣言されたデータにアクセスしている。まず,静的変数がそのデータ

用に,例えば大域的静的変数が,宣言される必要がある。 

.field public static int32 myInt at theInt 

次に,その静的変数は,そのデータをロードするために用いてもよい。 

ldsfld int32 myInt 

// data on stack 

16.4 非リテラル静的データの初期化 

注記 この細分箇条は参考情報であり規定ではない。 

198 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

静的データを扱う多くの言語では,プログラムの実行開始前にデータを初期化する方法を提供している。

これを行うために通常三つの機構があり,それぞれCLIでも提供している。 

16.4.1 リンク時に判明するデータ 

静的データに格納される正しい値が,プログラムのリンク時(又はリンク処理が存在しない言語におい

てはコンパイル時)に判明する場合,実際の値は,PEファイルに直接,典型的にはデータ領域に,格納す

ることができる(16.3参照)。変数への参照は,このデータが置かれるメモリ位置に対して直接なされる。

これには,リンカが仮定したアドレス以外の場所にファイルをロードする場合,この領域への任意の参照

を調整するために,OSが提供するアドレス決定機構を用いる。 

CLIにおいて,この技法が直接利用できるのは次の場合に限る。すなわち,静的変数が基底の数値型の

うちの一つをもつ場合,又は値型であって明示的な型配置をもち,かつ,管理下オブジェクトへの埋込み

参照をももたない場合のいずれかである。この技法が利用できる場合,データはデータ領域に通常どおり

割り当てられ,静的変数が特別なRVA(すなわち,PEファイルの先頭からのオフセット)に(at構文を

用いて)フィールド宣言でデータラベルを用いて割り当てられる。 

しかし,この機構は,アプリケーション領域(第1章参照)におけるCLI概念と合わない。アプリケー

ション領域は,二つのアプリケーションを同じOSプロセス内で動作させるために,お互いに共有データ

をもたないことを保証することで,互いに分離させることを意図して提供されている。しかし,PEファイ

ルはプロセス内で共有されるため,この機構を用いてアクセスされる任意のデータは,プロセス内のすべ

てのアプリケーション領域に対して可視となり,したがってアプリケーション領域分離境界を設定した意

図に反する。 

16.5 ロード時に判明するデータ 

注記 この細分箇条は参考情報であり規定ではない。 

PEファイルがロードされるまで,正しい値が不明である場合(例えば,幾つかのPEファイルがロード

されたアドレスに基づいて計算される値を含む場合),PEファイルがロードされる時に実行すべき任意の

コードを提供することが可能とする。しかし,この機構はプラットフォーム固有であり,すべてのCLI規

格適合処理系では動作しない可能性がある。 

16.5.1 実行時に判明するデータ 

型配置が計算されるまで正しい値が決定できない場合,その実装は,静的データを初期化する型初期化

子の一部としてコードを提供しなければならない。型初期化子に関する保証については,10.5.3.1に示す。

次で説明するとおり,大域的,かつ,静的なデータは,型に属するものではあるがCLIの中でモデル化さ

れる。したがって,同様な保証を,大域及び型に対して静的なデータの両方に適用する。 

管理下型の配置は,型が最初に参照されるまで出現する必要はないため,PEファイルに単純にデータを

配置することによって,管理下型を静的に初期化することはできない。代替として,次の段階に従う型初

期化処理が存在する。 

1) すべての静的変数をゼロにする。 

2) 実装者が提供する型初期化手続が,もしあれば,10.5.3で規定するように呼び出される。 

型初期化手続には,幾つかの技法が存在する。 

− 定数を静的変数の適切なフィールドに格納する明示生成コード。小さなデータ構造に対しては,これ

は効率的となり得るが,しかし,これは初期化子がプラットフォーム固有のコードに変換されること

を要請する。ここでプラットフォーム固有のコードは,コード領域及び実行時問題の両方となり得る。 

− ボックス化値型。静的変数が単に基底算術型をボックス化したもの又は明示的な配置をもつ値型であ

background image

199 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

る場合,ボックス化されていないインスタンスをもつ既知のRVAでの付加的な静的変数を導入し,続

いてbox命令を単純に用いてボックス化された複製を生成する。 

− 静的なプラットフォーム固有の配列データからの管理下配列の生成。これはプラットフォーム固有の

配列を管理下配列に組み換えることで得られる。プラットフォーム固有の配列に依存して,個々に組

換え処理を用いるべきである。例えば,安全な配列にできる。 

− 値型の管理下配列に対する省略時の初期化。基底クラスライブラリは,ボックス化されていない値型

の配列の各要素に対する領域をゼロにするメソッド 

(System.Runtime.CompilerServices.Initializearray)を提供している。 

17 特性の定義 

特性は,.property指令を用いて宣言される。特性は,型の内側でだけ宣言されなければならない(す

なわち,大域的特性は提供されていない。)。 

《クラスメンバ》 ::= 

  .property 《特性ヘッダ》 ʻ{ʼ 《特性メンバ》* ʻ}ʼ 

特性情報がどのようにメタデータに格納されるかについては,22.34及び22.35を参照する。 

《特性ヘッダ》::= 
 [ specialname ][ rtspecialname ] 《呼出し規約》《型》《識別子》 ʻ(ʼ 《仮引数群》 ʻ)ʼ 

.property指令は,呼出し規約(15.3参照),型,名前,及び括弧内に仮引数を指定する。specialname

は,その特性が他のツールに対して特別であると印付けをし,rtspecialnameは,その特性がCLIに対

して特別であると印付けをする。特性に対する識別情報(すなわち,《特性ヘッダ》生成規則)は,特性の.get

メソッドの識別情報と一致しなければならない(次を参照)。 

注記 根拠は次のとおりである。現時点では,rtspecialnameで印付けられることを要求される特

性名は存在しない。これは拡張,将来の標準化,及び特性並びにメソッドの宣言間での一貫性

を増加させるために提供されている(インスタンスメソッド及び型初期化子メソッドは,この

属性で印付けられなければならない。)。 

CLIが特性を作成するメソッドに何ら制約を課さないのに対し,CLS(第1章参照)は,一貫性に関す

る一連の制約を指定する。 

特性は,その本体に任意個数のメソッドを含むことができる。次の表は,これらのメソッドがどのよう

に識別されるかを示しており,各項目に対する簡単な記述を提供している。 

《特性メンバ》 ::= 

記述 

箇条又は 
細分箇条 

| .custom 《カスタム宣言》 

カスタム属性 

21 

| .get 《呼出し規約》《型》 [《型指定》 ʻ::ʼ ] 《メソッ
ド名》 ʻ(ʼ 《仮引数群》 ʻ)ʼ 

特性を取得側を指定する。 

| .other 《呼出し規約》 《型》 [《型指定》 ʻ::ʼ ] 《メ
ソッド名》 ʻ(ʼ 《仮引数群》 ʻ)ʼ 

特性を取得側又は設定側以外
のメソッドを指定する。 

| .set 《呼出し規約》《型》 [《型指定》 ʻ::ʼ ] 《メソッ
ド名》 ʻ(ʼ 《仮引数群》 ʻ)ʼ 

特性を設定側を指定する。 

| 《外部ソース宣言》 

ソース行情報 

5.7 

.getは,この特性を取得側を指定する。《型指定》の省略時は現在の型となる。取得側のただ一つだけ

が,特性を指定することができる。CLS合致となるためには,取得側の定義はspecialnameで印付けら

れていなければならない。 

.setは,この特性を配置する側を指定する。《型指定》の省略時は現在の型となる。設定側のただ一つ

background image

200 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

だけが,特性を指定することができる。CLS合致となるためには,設定側の定義はspecialnameで印付

けられていなければならない。 

.otherは,この特性を構成するその他(取得側及び設定側以外)のメソッドを指定するために使用す

る。 

さらに,カスタム属性(箇条21参照)又はソース行宣言が指定されてもよい。 

例 これは,countと呼ばれる特性の宣言を示す。 

.class public auto autochar MyCount extends [mscorlib]System.Object 

  .method virtual hidebysig public specialname instance int32 

get̲Count() { 

  // body of getter 

  } 

  .method virtual hidebysig public specialname instance void set̲Count( 

      int32 newCount) { 

  // body of setter 

  } 

  .method virtual hidebysig public instance void reset̲Count() { 

  // body of refresh method 

  } 

  // the declaration of the property 

  .property int32 Count() { 

    .get instance int32 get̲Count() 

    .set instance void set̲Count(int32) 

    .other instance void reset̲Count() 

  } 

18 イベントの定義 

イベントは型の内側で,.event指令を用いて宣言される。大域的なイベントは存在しない。 

《クラスメンバ》 ::= 

箇条 

  .event 《イベントヘッダ》 ʻ{ʼ 《イベントメンバ》* ʻ}ʼ 

| … 

22.13及び22.11を参照する。 

《イベントヘッダ》 ::= 

  [ specialname ] [ rtspecialname ] [《型指定》 ] 《識別子》 

典型的な利用では,《型指定》は(もしあれば)委譲を識別する。ここで委譲の識別情報は,イベントを

発生させるメソッドに渡される実引数と一致する。 

イベントの先頭には,予約語specialname又は予約語rtspecialnemaを含んでもよい。

specialnameは,他のツールに対する特性の名前を印付け,rtspecialnameは,イベントの名前が実

行時に特別であると印付ける。 

background image

201 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

注記 根拠は次のとおりである。現時点では,rtspecialnameで印付けられる必要のあるイベント

名は存在しない。これは拡張,将来の規格,及びイベント宣言とメソッド宣言間の一貫性を増

加させるために提供されている(インスタンス及び型初期化子メソッドは,この属性で印付け

られなければならない。)。 

《イベントメンバ》 ::= 

記述 

箇条又は
細分箇条 

  .addon 《呼出し規約》《型》 [《型指定》 ʻ::ʼ ] 《メソッド名》 
ʻ(ʼ 《仮引数群》 ʻ)ʼ 

イベントの追加メソッド  

| .custom 《カスタム宣言》 

カスタム属性 

21 

| .fire 《呼出し規約》《型》 [《型指定》 ʻ::ʼ ] 《メソッド名》 
ʻ(ʼ 《仮引数群》ʻ)ʼ 

イベントの発生メソッド  

| .other 《呼出し規約》《型》 [《型指定》 ʻ::ʼ ] 《メソッド名》 
ʻ(ʼ 《仮引数群》 ʻ)ʼ 

その他のメソッド 

| .removeon 《呼出し規約》《型》 [《型指定》 ʻ::ʼ ] 《メソッ
ド名》 ʻ(ʼ 《仮引数群》 ʻ)ʼ 

イベントの除去メソッド  

| 《外部ソース宣言》 

.line又は#line 

5.7 

.addon指令は,追加メソッドを指定し,《型指定》は,イベントと同じ型を省略時の値とする。CLS

は,名前付け規約及びイベントの一貫性制約を指定し,かつ,追加メソッドの定義がspecialnameで印

付けられることを要請する。 

.removeon指令は,除去メソッドを指定し,《型指定》は,イベントと同じ型を省略時の値とする。CLS

は,名前付け規約及びイベントの一貫性制約を指定し,かつ,除去メソッドの定義がspecialnameで印

付けられることを要請する。 

.fire指令は,発生メソッドを指定し,《型指定》は,イベントと同じ型を省略時の値とする。CLSは,

名前付け規約及びイベントの一貫性制約を指定し,かつ,発生メソッドの定義がspecialnameで印付け

られることを要請する。 

イベントは,.other指令で指定されたその他のメソッドを任意個数含んでもよい。CLIの観点から,

これらのメソッドは,イベントを通してお互いに関連付けられているだけである。それらが特別な意味を

もつ場合,実装者によって文書化されている必要がある。 

イベントは,それらと関連付けられたカスタム属性(箇条21参照)をもつことができる。それらはソー

ス行情報を宣言することができる。 

例 ここでは,イベントの宣言,それに対応する委譲,並びに,イベントの追加,除去,及び発生の

各メソッドの典型的な実装を示す。イベント及びメソッドは,Counterと呼ばれるクラスにて宣

言されている。 

// the delegate 

.class private sealed auto autochar TimeUpEventHandler extends 

     [mscorlib]System.Delegate { 

  .method public hidebysig specialname rtspecialname instance 

void .ctor(object 

      'object', native int 'method') runtime managed {} 

  .method public hidebysig virtual instance void Invoke() runtime managed 

{} 

  .method public hidebysig newslot virtual instance class 

202 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

    [mscorlib]System.IasyncResult BeginInvoke(class  

    [mscorlib]System.AsyncCallback callback, object 'object') runtime 

managed {} 

  .method public hidebysig newslot virtual instance void EndInvoke(class 

     [mscorlib]System.IAsyncResult result) runtime managed {} 

// the class that declares the event 

.class public auto autochar Counter extends [mscorlib]System.Object 

  // field to store the handlers, initialized to null 

  .field private class TimeUpEventHandler timeUpEventHandler 

  // the event declaration 

  .event TimeUpEventHandler startStopEvent { 

    .addon instance void Counter::add̲TimeUp(class TimeUpEventHandler 

'handler') 

    .removeon instance void Counter::remove̲TimeUp(class 

TimeUpEventHandler 'handler') 

    .fire instance void Counter::fire̲TimeUpEvent() 

  } 

  // the add method, combines the handler with existing delegates 

  .method public hidebysig virtual specialname instance void 

add̲TimeUp(class  

      TimeUpEventHandler 'handler') { 

    .maxstack 4 

    ldarg.0 

    dup 

    ldfld class TimeUpEventHandler Counter::TimeUpEventHandler 

    ldarg 'handler' 

    call class[mscorlib]System.Delegate  

      [mscorlib]System.Delegate::Combine(class 

[mscorlib]System.Delegate, class  

      [mscorlib]System.Delegate) 

    castclass TimeUpEventHandler 

    stfld class TimeUpEventHandler Counter::timeUpEventHandler 

    ret 

  } 

  // the remove method, removes the handler from the delegate 

  .method virtual public specialname void remove̲TimeUp(class 

TimeUpEventHandler 'handler') { 

background image

203 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

    .maxstack 4 

    ldarg.0 

    dup 

    ldfld class TimeUpEventHandler Counter::timeUpEventHandler 

    ldarg 'handler' 

    call class[mscorlib]System.Delegate 

       [mscorlib]System.Delegate::Remove(class  

       [mscorlib]System.Delegate, class [mscorlib]System.Delegate) 

    castclass TimeUpEventHandler 

    stfld class TimeUpEventHandler Counter::timeUpEventHandler 

    ret 

  } 

  // the fire method 

  .method virtual family specialname void fire̲TimeUpEvent() { 

    .maxstack 3 

    ldarg.0 

    ldfld class TimeUpEventHandler Counter::timeUpEventHandler 

    callvirt instance void TimeUpEventHandler::Invoke() 

    ret 

  } 

} // end of class Counter 

19 例外処理 

CLIではメソッドは,“保護されている”と呼ばれるCIL命令の区間を定義することができる。これはtry

ブロックと呼ばれる。これは,次にそのtryブロックに対する一つ以上のハンドラと関連付けることがで

きる。tryブロック中の任意の場所で実行中に例外が起こった場合,その問題を記述した例外オブジェクト

が生成される。CLIは,処理を引き継ぎ,例外が送出された箇所から,その例外を処理すべきコードのブ

ロックへ制御を移す。第1章を参照。 

どの二つのハンドラ(fault,filter,catch,又はfinally)も同じ開始アドレスをもつことはで

きない。例外が起きると,実行アドレスを例外が起こった,正しい構文的に最も入れ子になったtryブロ

ックへと変換する必要がある。 

《構造化例外ブロック》 ::= 

  《tryブロック》《構造化例外節》 [《構造化例外節》* ] 

細分箇条19.1〜19.6では,例外処理を分担する5種類のコードブロック,try,catch,filter,finally,

及びfaultについて説明を加える(《tryブロック》中に与えられる《構造化例外節》の個数及び種類につ

いては,制限があることに注意されたい。第1章参照)。 

残った構文要素については,次で詳細に述べる。これらは参照用にここに集約されている。 

《tryブロック》 ::= 

記述 

.try《ラベル》to《ラベル》 

第1ラベルから第2ラベルの直前までの保護区域 

| .try《有効範囲ブロック》 

《有効範囲ブロック》は保護される。 

background image

204 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

《構造化例外節》 ::= 

記述 

  catch 《型参照》 《ハンドラブロック》 指定された型のすべてのオブジェクトを捕そく(捉)する。 

| fault 《ハンドラブロック》 

通常の出口以外のすべての例外を処理する。 

| filter Label 《ハンドラブロック》 

filterが成功した場合,ハンドラに入る。 

| finally 《ハンドラブロック》 

すべての例外と通常の出口を処理する。 

《ハンドラブロック》::= 

記述 

handler 《ラベル》 to 《ラベル》 

ハンドラ区間は,第1ラベルから第2ラベルの直前までとする。 

| 《有効範囲ブロック》 

《有効範囲ブロック》は,ハンドラブロックとする。 

19.1 限定公開ブロック 

tryブロック,又は保護ブロック,又は防護ブロックは,.try指令を用いて宣言される。 

《tryブロック》 ::= 

記述 

.try 《ラベル》 to 《ラベル》 

第1ラベルから第2ラベルの直前までの保護区域 

| .try 《有効範囲ブロック》 

《有効範囲ブロック》は保護される。 

第1の記述では,保護ブロックは二つのラベルによって区切られている。第1のラベルは,保護される

べき最初の命令であるのに対し,第2のラベルは,保護されるべき最後の命令の次の命令とする。いずれ

のラベルもこの時点に先立って定義されていなければならない。 

第2の記述は,.try指令に続き有効範囲ブロック(15.4.4参照)を用いている。その有効範囲内の命令

は保護されるべき命令とする。 

19.2 ハンドラブロック 

《ハンドラブロック》 ::= 

記述 

| handler 《ラベル》 to 《ラベル》 

ハンドラ区域は,第1ラベルから第2ラベルの直前までとする。 

| 《有効範囲ブロック》 

《有効範囲ブロック》は,ハンドラブロックとする。 

第1の記述では,ラベルがハンドラブロックを囲っている。第1のラベルはハンドラブロックの最初の

命令であるのに対し,第2のラベルは,ハンドラの直後の命令とする。第2の記述では,ハンドラブロッ

クは単に有効範囲ブロックとなる。 

19.3 catchブロック 

catchブロックは,予約語catchを使って宣言される。これは,その節で扱うように記述された例外

オブジェクトの型,及びハンドラコード自身を指定する。 

《構造化例外節》 ::= 

  catch 《型参照》 《ハンドラブロック》 

例 

.try { 

 ... 

// protected instructions 

 leave exitSEH  

// normal exit 

} catch [mscorlib]System.FormatException { 

 ... 

// handle the exception 

 pop 

// pop the exception object 

 leave exitSEH  

// leave catch handler 

exitSEH:  

// continue here 

background image

205 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

19.4 フィルタブロック 

フィルタブロックは,予約語filterを用いて宣言される。 

《構造化例外節》 ::= … 

| filter 《ラベル》 《ハンドラブロック》 

| filter 《有効範囲》 《ハンドラブロック》 

フィルタコードは,指定されたラベルで始まり,ハンドラブロックの最初の命令で終了する(CLIは,

CILストリーム中で,フィルタブロックが対応するハンドラブロックの直前になければならないことを要

請していることに注意する。)。 

例 

.method public static void m () { 

    .try { 

      ...  

// protected instructions 

      leave 

exitSEH // normal exit 

    } 

    filter { 

      ...  

// decide whether to handle 

      pop  

// pop exception object 

      ldc.i4.1 

// EXCEPTION̲EXECUTE̲HANDLER 

      endfilter 

// return answer to CLI 

    } 

    { 

      ...  

// handle the exception 

      pop  

// pop the exception object 

      leave 

exitSEH // leave filter handler 

    } 

exitSEH: 

    ... 

19.5 finallyブロック 

finallyブロックは,予約語finallyを用いて宣言される。これはハンドラコードを,次の文法で指

定する。 

《構造化例外節》 ::= … 

| finally 《ハンドラブロック》 

finallyハンドラで実行可能な最後のCIL命令は,endfinallyでなければならない。 

例 

.try { 

 ... 

// protected instructions 

 leave exitTry  

// shall use leave 

} finally { 

 ... 

// finally handler 

background image

206 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

 endfinally 

exitTry:  

// back to normal 

19.6 faultハンドラ 

faultブロックは,予約語faultを用いて宣言される。これは,ハンドラコードを次の文法によって

指定する。 

《構造化例外節》 ::= … 

| fault 《ハンドラブロック》 

faultハンドラで実行可能な最後のCIL命令は,endfaultでなければならない。 

例 

.method public static void m() { 

  startTry: 

 ... 

// protected instructions 

 leave exitSEH // shall use leave 

  endTry: 

startFault: 

 ... 

// fault handler instructions 

 endfault 

endFault: 

 .try startTry to endTry fault handler startFault to endFault 

exitSEH:  

// back to normal 

20 セキュリティ宣言 

CLIを使う多くの言語は,メタデータ内の項目にセキュリティ宣言属性を付加する属性構文を用いる。

この情報は,コンパイラによって,XML記述に変換されメタデータに蓄えられる(22.11参照)。対照的に,

ilasmでは,そのXMLに変換された情報を入力に記述する必要がある。 

《セキュリティ宣言》 ::= 

  .permissionset 《セキュリティ動作》 = ʻ(ʼ《バイト列》 ʻ)ʼ 

| .permission 《セキュリティ動作》 《型参照》 ʻ(ʼ《名前値対列》 ʻ)ʼ 

《名前値対列》 ::= 《名前値対》> [ ʻ,ʼ《名前値対》]* 

《名前値対》 ::= 《一重引用符文字列》 ʻ=ʼ 《一重引用符文字列》 

.permissionの《型参照》は,許可クラスを指定し,《名前値対列》は,設定を指定する(22.11参照)。 

上の .permissionset構文の《バイト列》は,セキュリティ設定の符号化された版を規定する。 

《セキュリティ動作》 ::= 

説明 

  assert 

アクセス許可を主張する。それゆえ,呼出し側はそ
れを必要としない。 

| demand 

すべての呼出し側のアクセス許可があると要求する 

| deny 

アクセス許可を否定する。それゆえ,アクセス検査
が失敗する。 

background image

207 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

| inheritcheck 

下位クラスのアクセス許可を要求する。 

| linkcheck 

呼出し側のアクセス許可があると要求する。 

| permitonly 

アクセス許可を削減する。それゆえ,アクセス検査
が失敗する。 

| reqopt 

選択可能な追加のアクセス許可を請求する。 

| reqrefuse 

アクセス許可を認めない。 

| request 

アクセス許可が必要だと示唆する。 

21 カスタム属性 

カスタム属性は,メタデータに利用者定義の注記を追加する。カスタム属性によって,型のインスタン

スがメタデータの任意の要素とともに蓄えられるようになる。この機構を使えば,アプリケーション特有

の情報をコンパイル時に蓄え,実行時又は他のツールがそのメタデータを読む時にアクセスできる。任意

の利用者定義の型が属性として使えるが,CLS合致であるためには,その属性は,親が

System.Attributeである型のインスタンスでなければならない。CLIは,幾つかの属性型を前もって

定義しており,実行時の振る舞いを制御するのに使っている。言語によっては,CTSで直接表現されない

その言語の特性を表現するために前もって属性型を定義している。利用者もツールも追加の属性型を定義

して使うことを奨励する。 

カスタム属性は,指令.customを用いて宣言される。この指令の後に,型構成子のためのメソッド定義

が続く。さらに,括弧で囲まれた《バイト列》が続いてもよい。 

《カスタム宣言》 ::= 

  《構築子》 [ ʻ=ʼ ʻ(ʻ《バイト列》 ʻ)ʼ ] 

項目《構築子》は,メソッド名が.ctorのメソッド宣言(15.4参照)を表す。 

次に例を示す。 

例 

.custom instance void myAttribute::.ctor(bool, bool) = ( 01 00 00 01 

00 00 ) 

カスタム属性は,カスタム属性そのものを除いて,メタデータの任意の項目に付加できる。通常は,カ

スタム属性は,アセンブリ,モジュール,クラス,インタフェース,値型,メソッド,フィールド,特性,

総称仮引数及びイベントに付加される(カスタム属性は,直前の宣言に付加される。)。 

項目《バイト列》は,構築子が実引数をとらない場合は必要ない。その場合,カスタム属性が存在する

かどうかだけが問題となる。 

構築子が引数をとる場合には,その値が項目《バイト列》で規定されなければならない。このʻblobʼの形

式は23.3で定義される。 

例 次の例は,System.CLSCompliantAttribute

で印付けられたクラス及び

System.ObsoleteAttributeで印付けられたメソッドを示す。 

.class public MyClass extends [mscorlib]System.Object 

{ .custom instance void 

[mscorlib]System.CLSCompliantAttribute::.ctor(bool) = ( 01 00 01 00 

00 ) 

 .method public static void CalculateTotals() cil managed 

   { .custom instance void [mscorlib] System.ObsoleteAttribute::.ctor 

background image

208 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

() = ( 01 00 00 00 ) 

    ret 

 } 

21.1 CLS記法 カスタム属性使用例 

CLSでは,言語をまたいだ操作を向上させるためにカスタム属性の仕様に関して記法を規定する。詳細

は,第1章を参照。 

21.2 CLIで使われる属性 

カスタム属性には,真性カスタム属性及び擬似カスタム属性の2種類がある。真性カスタム属性と擬似

カスタム属性とは,次に示すように,定義時の扱いが異なる。 

− 真性カスタム属性は,直接メタデータに蓄えられる。定義データを保持するʻblobʼは,そのまま蓄えら

れる。そのʻblobʼは,後で取り出される。 

− 擬似カスタム属性は,名前が短並びの一つなので認識される。ʻblobʼは,メタデータに直接蓄えられる

のではなく,構文解析され,保持する情報が,メタデータ表内のビット及び/又はフィールドの設定

に使われる。ʻblobʼは,その後破棄される。後に取り出すことはできない。 

したがって,擬似カスタム属性は,コンパイラが真性カスタム属性に提供するのと同じ構文を用いた利

用者指令として役立つが,この利用者指令は,メタデータ表にメモリ効率に優れた形式で蓄えられる。こ

の形式の表では,真性カスタム属性よりも実行時の検査が高速でもある。 

多くのカスタム属性は,ソフトウェアのより高位の階層で創出される。それらは,CLIがその意味を知

ることなく,すなわち,それが“意味するところ”を気にかけることなく,蓄えられ返される。しかし,

擬似カスタム属性及び一部の真性カスタム属性は,コンパイラ及びCLIにとって特別な意義をもつ。その

ようなカスタム属性の例に,System.Reflection.DefaultMemberAttributeがある。これは,メタ

データに真性カスタム属性ʻblobʼとして蓄えられるが,型の省略時メンバ(特性)を呼び出す時には,自己

反映がこのカスタム属性を用いる。 

21.2.1〜21.2.5では,すべての擬似カスタム属性及び特別なカスタム属性を示す。ここで,特別なという

意味は,CLI及び/又はコンパイラが特別の注意を払い,その振る舞いがなんらかで影響されることを示

す。 

将来の名前衝突を防ぐために,名前空間Systemのすべてのカスタム属性は,標準化のために予約され

ている。 

21.2.1 擬似カスタム属性 

次の表は,CLI擬似カスタム属性を示す。(この規格では,これらすべての擬似カスタム属性を規定する

わけではない。しかし,すべてが予約されており,他の目的に使ってはならない。これらの属性の詳細に

ついては,第4章の対応するクラスの文書を参照。)これらは,名前空間System.Reflection,

System.Runtime.CompilerServices及びSystem.Runtime.InteropServicesで定義される。 

属性 

説明 

AssemblyAlgorithmIDAttribute 使っているハッシュアルゴリズムのIDを記録する(予約専用)。 
AssemblyFlagsAttribute 

このアセンブリのためのフラグを記録する(予約専用)。 

DllImportAttribute 

管理外ライブラリ内で実装されたコードについての情報を提供
する。 

FieldOffsetAttribute 

取り囲むクラス又は値型の中でのフィールドのバイトオフセッ
トを示す。 

background image

209 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

属性 

説明 

InAttribute 

メソッド仮引数が[in]引数であることを示す。 

MarshalAsAttribute 

データ項目が管理下コードと管理外コードとの間でどのように
組み換えられなければならないかを示す(23.4参照。)。 

MethodImplAttribute 

メソッド実装の詳細を示す。 

OutAttribute 

メソッド仮引数が[out]引数であることを示す。 

StructLayoutAttribute 

呼出し側がクラス又は値型のフィールドを管理下メモリにおい
てどのように配置するか制御することを許す。 

これらの擬似カスタム属性は,次のとおりメタデータのビット及びフィールドに作用する。 

AssemblyAlgorithmIDAttribute フィールドAssembly.HashalgIdを設定する。 

AssemblyFlagsAttribute フィールドAssembly. Flags を設定する。 

DllImportAttribute 属性メソッドのためにビットMethod.Flags.PinvokeImplを設定する。さらに,

表ImplMapの中に新しい行要素を追加する(ただし,欄MappingFlags,欄MemberForwarded,欄ImportName

及び欄ImportScopeを設定する。)。 

FieldOffsetAttribute 属性フィールドのためにFieldLayout.OffSet値を設定する。 

InAttribute 属性付き仮引数のためにビットParam.Flags.Inを設定する。 

MarshalAsAttribute 属性フィールドのためにビットField.Flags.HasFieldMarshalを立てる(又は,

属性仮引数のためにビットParam.Flags.HasFieldMarshalを立てる。)。さらに,表NativeTypeに新しい行要

素を追加して,欄Parent 及び欄NativeTypeを設定する。 

MethodImplAttribute 属性メソッドのフィールドMethod.ImplFlagsを設定する。 

OutAttribute 属性仮引数のビットParam.Flags.Outを設定する。 

StructLayoutAttribute 属性型のために下位フィールドTypeDef.Flags.LayoutMaskを設定する。さ

らに,その型の下位フィールドTypeDef.Flags.StringFormatMask,並びにフィールドClassLayout.PackingSiz

及びClassLayout.ClassSizeを設定しても構わない。 

21.2.2 CLSによって定義されるカスタム属性 

CLSでは,幾つかのカスタム属性を規定しており,適合言語はそれらを使えるようにしなければならな

い。これらの属性は,Systemの下に位置付けられる。 

属性 

説明 

AttributeUsageAttribute 属性がどのように使われると意図されているかを示す。 
ObsoleteAttribute 

要素が使われてはならないことを示す。 

CLSCompliantAttribute 

要素が属性オブジェクト上のインスタンスフィールドによってCLS合
致と宣言されているかどうかを示す。 

21.2.3 セキュリティのためのカスタム属性 

次のカスタム属性は,名前空間System.NET及びSystem.Security.Permissionsで定義される。

これらはすべて基盤クラスであることに注意する。アセンブリで見られるセキュリティ属性の実際のイン

スタンスは,これらの下位クラスとなる。 

属性 

説明 

CodeAccessSecurityAttribute 

これは,カスタム属性を使ったセキュリティ宣言
のための基底属性クラスとなる。 

DnsPermissionAttribute 

DnsPermissionをもつセキュリティ宣言のためのカ
スタム属性クラス。 

EnvironmentPermissionAttribute 

EnvironmentPermissionをもつセキュリティ宣言の
ためのカスタム属性クラス。 

background image

210 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

FileIOPermissionAttribute  

FileIOPermissionをもつセキュリティ宣言のための
カスタム属性クラス。 

ReflectionPermissionAttribute 

ReflectionPermissionをもつセキュリティ宣言のた
めのカスタム属性クラス。 

SecurityAttribute 

これは,CodeAccessSecurityAttributeが導出される
セキュリティ属性のための基底属性クラスであ
る。 

SecurityPermissionAttribute 

属性が与えられたメソッドがセキュリティ設定に
影響するかどうかを示す。 

SocketPermissionAttribute 

SocketPermissionをもつセキュリティ宣言のための
カスタム属性。 

WebPermissionAttribute 

WebPermissionをもつセキュリティ宣言のための
カスタム属性。 

アセンブリに含まれたその他のセキュリティ関連カスタム属性(例えば, 

System.Security.Permissions.SecurityAttributeから導出されたあらゆるカスタム属性)は,

CLIの規格適合処理系によってロード時に拒否されたり,実行時にそれらのセキュリティ関連カスタム属

性へのアクセスが試みられるなら例外を投げる可能性がある(これは,実際,解決できない任意のカスタ

ム属性について真となる。セキュリティカスタム属性は,そのような具体例の一つに過ぎない。)。 

21.2.4 TLSのためのカスタム属性 

フィールドTLS(スレッド局所記憶域)を表記するカスタム属性は,名前空間Systemにおいて定義さ

れる。 

属性 

説明 

ThreadStaticAttribute 

スレッドに関係づけられた型メンバフィールドを提供する 

21.2.5 各種のカスタム属性 

次のカスタム属性が,CLIの各種側面を制御する。 

属性 

名前空間 

記述 

ConditionalAttribute 

System.Diagnostics 

コンパイル時の条件に基づき,メソッド
を呼出し可能に印付けるために使う。条
件が偽ならば,メソッドは呼び出されな
い。 

DecimalConstantAttribute 

System.Runtime.Compil
erServices 

十進定数の値をメタデータに蓄える。 

DefaultMemberAttribute 

System.Reflection 

自己反映のInvokeMemberが使う省略時
のメンバである,型のメンバを定義す
る。 

FaultModeAttribute 

System.Runtime.Compil
erServices 

命令チェックからの例外が適切か不適
切かを示す。 

FlagsAttribute 

System 

列挙がビットフィールド,すなわち,フ
ラグの集合として扱わなければならな
いことを示すカスタム属性。 

IndexerNameAttribute 

System.Runtime.Compil
erServices 

一つ以上の仮引数をもつ特性が,そのよ
うな機能を直接には扱わないプログラ
ム言語で使われるときの名前を示す。 

ParamArrayAttribute 

System 

呼出し時に可変個数の実引数を許すメ
ソッドであることを示す。 

211 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

22 メタデータ論理形式 表 

箇条22は,メタデータを記述する構造及びそれらがどのように相互に添字で指されるかを定義する。こ

れは,PE(可搬実行)ファイルからメモリに読み込まれた後,どのようにメタデータが配置されるかに対

応する(PEファイルそのものの内部でのメタデータ配置の記述は,箇条24を参照。)。 

メタデータは,表(レコードの配列)及びヒープという2種類の構造に蓄えられる。どのモジュールに

も,String,Blob,Userstring及びGUIDという四つのヒープがある。String,Blob及びUserstringは,バイ

ト配列である(ヒープへの添字は,0,23,25,39のようになる。)。ヒープGUIDは,それぞれが16バイ

トの長さのGUIDの配列となる。最初の要素が1,次の要素が2と順序付けられる。 

各表の各欄の入力は,定数又は添字となる。 

定数は,リテラル値(例えば,表Assemblyの欄HashalgIdに蓄えられるALG̲SID̲SHA1 = 4),又は,よ

り一般的には,ビットマスクとなる。ほとんどのビットマスク(たいていフラグと呼ばれる)は,2バイ

ト長(表Fieldの欄Flags)となるが,4バイト(表TypeDefの欄Flags)となるものもわずかにある。 

各添字は,2バイト長又は4バイト長となる。添字は,別の(若しくは同じ)表を指す,又は,四つの

ヒープの中の一つを指す。表の各添字欄のサイズは,特定のモジュールが,必要とする場合だけ4バイト

とする。したがって,最高行要素番号が2バイト値の範囲に収まる(複数個も許す)表を指す列について

は,添字子欄は2バイト長だけを必要とする。逆に言えば,64k行要素以上を含む巨大な表では,表の添

字子が4バイト長となる。 

添字が1で始まり,これがメタデータ表の先頭行要素を意味することに注意する。ゼロという添字値は,

全く行要素を指さない(null参照と同様に振る舞う。)。 

メタデータ表を指す欄には次の2種類がある。(これらの表の物理的表現の詳細は,24.2.6を参照。) 

− 単純 ― 欄は,ただ一つだけの表を指す。例えば,表TypeDefの欄FieldListは,常に表Fieldを指

す。したがって,その欄のすべての値は,単純整数となり,参照先の表の行要素番号を与える。 

− 符号化 ― 欄は,幾つかの表のいずれかを指す。例えば,表TypeDefの欄Extendsは,表TypeDef

又は表TypeRefを指す。添字の値の数ビットは,それが参照先の表を定義するために予約されている。

ほとんどの部分で,この規定は,参照先の表内の行要素数に復号化された後の添字値について述べる。

しかし,この規定には,メタデータの物理的配置を記述する節(箇条24)で,この符号化添字の記述

を含む。 

メタデータは,コンパイラ又はコード生成器によって作られた名前文字列を変更せずに保存する。本質

的には,それは,各文字列を不透明なblobとして扱う。特に,大文字と小文字とを保存する。メタデータ

に保存され,CLIでその後処理される名前のサイズにCLIは上限を設けない。 

AssemblyRef及びModuleRefを対応するアセンブリやモジュールに対応付ける時には,大文字と小

文字との違いを無視する(第1章参照)。しかし,(型,フィールド,メソッド,特性,イベント。)とい

う他のすべての名前については,厳密に対応付けるから,OSが大文字と小文字との違いを考慮するかど

うかには関係なく,すべてのプラットフォームで名前解決は同じとなる。 

表には,名前(例えば,”Assembly”)及び番号(例えば,0x20)の両方が与えられる。各表の番号は,

22.2〜22.36において,それらの表題の直後に与える。表番号は,PEファイルにおいて対応する表が出現

する順序を示し,与えられた表が存在するかどうかを示すビット集合(24.2.26参照)がある。表の番号は,

そのビット集合における位置である。 

幾つかの表は,通常のCLIファイルの拡張を表現する。特に,一時的なイメージで出現するENCLog及

びENCMapは,デバッグ中の"編集して継続",すなわち,"増分的コンパイル"シナリオで生成される。両

background image

212 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

方とも将来の使用のために予約されている。 

型のメソッド又はフィールドへの参照は,表MemberRefと呼ばれるメタデータ表に一緒に蓄えられる。

しかし,時々は,より明確な説明のために,この規格においては,この2種類の参照を区別し,“MethodRef”

及び“FieldRef”と呼ぶ。 

表によっては,次のとおり,主キーで整列化する必要がある。 

表 

主キー欄 

ClassLayout 

Parent 

Constant 

Parent 

CustomAttribute 

Parent 

DeclSecurity 

Parent 

FieldLayout 

Field 

FieldMarshal 

Parent 

FieldRVA 

Field 

GenericParam 

Owner 

GenericParamConstraint 

Owner 

ImplMap 

MemberForwarded 

InterfaceImpl 

Class 

MethodImpl 

Class 

MethodSemantics 

Association 

NestedClass 

NestedClass 

さらに,表InterfaceImplは,欄Interfaceを二次キーとして整列化され,表GenericParamは,欄Number

を二次キーとして整列化される。 

最後に,表TypeDefは,特別な順序制約をもつ。すなわち,取り囲むクラスの定義は,それが取り囲む

すべてのクラスの定義よりも先行しなければならない。 

メタデータ項目(メタデータ表のレコード)は,メタデータトークンによって番地付けされる。符号化

されていないメタデータトークンは,4バイトの符号なし整数であり,最大有効バイトにメタデータ表の

添字を保持して,最下位3バイトに1を底とするレコード添字を保持する。メタデータ表とそのそれぞれ

の添字は,22.2〜22.39で記述する。 

符号化メタデータトークンも表及びレコード添字を保持するが,その形式は異なる。符号化の詳細につ

いては,24.2.6を参照せよ。 

22.1 メタデータ妥当性確認規則 

注記 ここから参考情報であり規定ではない。 

22.2〜22.39は,メタデータ表の種類ごとにスキーマを記述して,PEファイルに生成されたメタデータ

が妥当であることを保証する規則の詳細を説明する。メタデータが妥当なことを確認することは,型安全

性のためのCIL命令ストリームの検査,メソッド表の構築,CLIからプラットフォーム固有コードへのコ

ンパイル,データ並び換えなどの後の処理が,CLIを壊したり,安全でない振る舞いをしないことを保証

する。 

さらに,規則の幾つかは,妥当なメタデータかどうかには関係しないにもかかわらず,CLS要求(第1

章参照)に合致しているかを検査するのにも使われる。そのような規則は,タグ[CLS]という印がついて

いる。 

妥当なメタデータの規則は,個別のモジュールを参照する。モジュールは,典型的にはディスクファイ

ルに保存されるメタデータの集まりとする。これには,コンパイラ及びリンカの出力,又は,(メタデータ

は,メモリ中にだけ存在し,実際には,ディスク上のファイルに保存されることがない。)スクリプトコン

213 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

パイラの出力を含む。 

規則は,モジュール内の妥当性検証だけを扱う。したがって,この規格への適合性検証ソフトウェアは,

例えば,他のモジュールで定義された参照の解決も型階層の走査も行う必要がない。しかし,たとえ,A

及びBという二つのモジュールが別々に分析され,妥当なメタデータだけを保持するとしても,これらを

合わせるとエラーになる可能性があることは,明らかにしておかなければならない(例えば,モジュール

AからモジュールBで定義されたメソッドの呼出しは,Bのそのメソッドのために定義された呼出し情報

と一致しない呼出し元識別情報を規定しているかもしれない。)。 

検査結果は,次のとおりERROR,WARNING 又はCLSに分類される。 

− ERRORは,CLIのクラッシュ又はハングアップを引き起こすものを報告する。実行できるが間違った

答えを生成したり,全く良性のものもある。規則ERRORに違反するメタデータを受理しないCLI規

格適合実装もあり得るから,そのようなメタデータは,不当であり,可搬でない。 

− WARNINGは,実際に間違っているというわけではないが,コンパイラにとっては問題となるものを

報告する。通常は,同じ情報をコンパイラではより簡潔に符号化できるか,又は,メタデータが実時

間に実際に使えない構築子を表現する場合を示す。すべての規格適合実装は,規則WARNINGだけに

違反するメタデータを取り扱う。したがってそのようなメタデータは,妥当,かつ,可搬となる。 

− CLSは,共通言語仕様(第1章参照)に対して合致していないものを報告する。そのようなメタデー

タは,妥当,かつ,可搬であり,CLIのすべての規格適合実装が構築子を取り扱えても,なお処理不

能なプログラム言語が存在しうる。 

妥当性確認規則は,次の分類となる。 

− 行要素数 一つの行要素だけを許す表(例えば,Module)が幾つかある。ほとんどの表はこのような

制限をもたない。 

− 一意な行要素 どの表も重複した行要素をもってはならない。ここで,“重複”は,キーとなる欄又は

欄の組合せで定義される。 

− 妥当な添字 添字となる欄は,次のとおり意味のある内容を指さなければならない。 

− ヒープString,Blob又はUserstringへのどの添字も,ヒープ内部への位置を指し示さなければなら

ず,その開始位置(オフセット0)より前又は末尾より後ろを指し示してはならない。 

− ヒープGUIDへのどの添字も,1と,このモジュールの最大要素個数との間の範囲となる。 

− 他のメタデータ表への添字(行要素番号)は,0とその表の行要素数 + 1との間になければならな

い(表によっては,添字が参照先の表の末尾を超えた位置を示し,何も指していないことを意味す

る。)。 

− 妥当なビットマスク ビットマスクである欄では,ビット集合の妥当な置換だけをもたなくてはなら

ない。 

− 妥当なRVA RVA(相対仮想アドレス。対応するPEファイルがメモリにロードされたアドレスから

のバイトオフセットとなる。)が代入されたフィールド及びメソッドへの制約がある。 

次に述べる規則には,実際には何も言っていないものもあることに注意する。例えば,表がゼロ個以上

の行要素を許すという規則があり,これでは,違反しているか検査できない。このような規則は,単に規

則を完全なものにするためであり,そのような詳細が見過ごされておらず,きちんと述べられていること

だけを記録する。 

注記 参考情報終わり 

CLIは,メタデータに蓄えられる名前の長さには制限を設けず,CLI実装によって処理される。 

214 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

22.2 Assembly : 0x20 

表Assemblyは,次の欄をもつ。 

− HashalgId(型AssemblyHashAlgorithmの4バイト定数。23.1.1参照) 

− MajorVersion,MinorVersion,BuildNumber,RevisionNumber(それぞれ,2バイト定数。) 

− Flags(型AssemblyFlagsの4バイトビットマスク。23.1.2参照) 

− PublicKey(ヒープBlobへの添字) 

− Name(ヒープStringへの添字) 

− Culture(ヒープStringへの添字) 

表Assemblyは,指令.assemblyを用いて定義される(6.2参照)。その欄は,.hash 

algorithm,.ver,.publickey及び.cultureから得られる(6.2.1参照)。例は,6.2を参照。 

注記 ここから参考情報であり規定ではない。 

1) 表Assemblyは,ゼロ個以上の行要素を含む。[ERROR] 

2) HashalgIdは,規定された値のいずれかでなければならない。[ERROR] 

3) MajorVersion, MinorVersion, BuildNumber, 及びRevisionNumberは,それぞれ任意の値をもってよい。 

4) Flagsは,規定された値集合だけをもつことができる。[ERROR] 

5) PublicKeyは,null又は非nullとなる。 

6) Nameは,ヒープStringにおいて非空文字列を指す。[ERROR] 

7) Nameによって添字される文字列は,長さが無限でもよい。 

8) Cultureは,null又は非nullとなる。 

9) Cultureが非nullならば,規定された並びのうちの単一の文字列を指す(23.1.3参照)。[ERROR] 

注記 Nameは,単純名とする(例えば,“Foo”,ドライブ文字,パス,ファイル拡張子はない。)。

POSIX合致システムでは,Nameには,コロン,斜線,逆斜線,ピリオドを含まない。 

注記 

参考情報終わり 

22.3 AssemblyOS : 0x22 

表AssemblyOSは,次の欄をもつ。 

− OSPlatformID(4バイト定数) 

− OSMajorVersion(4バイト定数) 

− OSMinorVersion(4バイト定数) 

これらレコードは,どのPEファイルにも生成しないほうがよい。もし,PEファイルにある場合には,

すべてのフィールドがゼロであるかのように扱わなければならない。CLIは,それを無視しなければなら

ない。 

22.4 AssemblyProcessor : 0x21 

表AssemblyProcessorは,次の欄をもつ。 

− Processor(4バイト定数) 

このレコードは,どのPEファイルにも生成しないほうがよい。もしも,PEファイルにある場合には,

すべてのフィールドがゼロであるかのように扱うのが望ましい。CLIは,それを無視するのが望ましい。 

22.5 AssemblyRef : 0x23 

表AssemblyRefは,次の欄をもつ。 

− MajorVersion,MinorVersion,BuildNumber,RevisionNumber(それぞれ,2バイト定数) 

− Flags(型AssemblyFlagsの4バイトビットマスク,23.1.2参照) 

215 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

− PublicKeyOrToken(ヒープBlobへの添字。このAssemblyの作者を識別する公開かぎ(鍵)又はトー

クン。) 

− Name(ヒープStringへの添字。) 

− Culture(ヒープStringへの添字。) 

− HashValue(ヒープBlobへの添字。) 

表は,指令.assembly externで定義される(6.3参照)。その欄は,指令.publickeytokenを用い

て定義される欄PublicKeyOrTokenを除いては,表Assemblyと同様な指令を用いて埋められる。例は,6.3

を参照。 

注記 ここから参考情報であり規定ではない。 

1) MajorVersion,MinorVersion,BuildNumber,RevisionNumberは,それぞれ任意の値をもってよい。 

2) Flagsでは,PublicKeyビットの1ビットだけが設定される可能性がある(23.1.2参照)。他のすべて

のビットはゼロとする。[ERROR] 

3) PublicKeyOrTokenは,null又は非nullとなる(ビットFlags.PublicKeyは,'blob'が完全公開かぎ(鍵)

又は短ハッシュかぎ(鍵)かいずれであるかを規定することに注意する。)。 

4) 非nulならば,PublicKeyOrTokenは,ヒープBlobでの妥当なオフセットを指さなければならない。

[ERROR] 

5) Nameは,ヒープStringにおける非空文字列を指さなければならない(長さには制限がない。)。[ERROR] 

6) Cultureは,null又は非nullとなる。 

7) 非nullならば,指定された並びのうちの単一の文字列を指さなければならない(23.1.3参照)。[ERROR] 

8) HashValueは,null又は非nullとなる。 

9) 非nullならば,HashValueは,ヒープBlobでの空でない'blob'を指さなければならない。[ERROR] 

10) 表AssemblyRefは,冗長があってはならない。ここで冗長な行要素とは,同じMajorVersion,MinorVersion,

BuildNumber,RevisionNumber,PublicKeyOrToken,Nam及びCultureをもつことをいう。[WARNING] 

注記 Nameは,単純名とする(例えば,“Foo”,ドライブ文字,パス,ファイル拡張子はない。)。

POSIX合致システムでは,Nameには,コロン,斜線,逆斜線,ピリオドを含まない。 

注記 参考情報終わり 

22.6 AssemblyRefOS : 0x25 

表AssemblyRefOSは,次の欄をもつ。 

− OSPlatformId(4バイト定数) 

− OSMajorVersion(4バイト定数) 

− OSMinorVersion(4バイト定数) 

− AssemblyRef (表AssemblyRefへの添字) 

これらのレコードは,どのPEファイルにも生成しないほうがよい。もし,PEファイルにある場合には,

あたかもフィールドがゼロであるかのように扱うのが望ましい。CLIは,それを無視するのが望ましい。 

22.7 AssemblyRefProcessor : 0x24 

表AssemblyRefProcessorは,次の欄をもつ。 

− Processor(4バイト定数) 

− AssemblyRef (表AssemblyRefへの添字) 

これらのレコードは,どのPEファイルにも生成しないほうがよい。もし,PEファイルにある場合には,

あたかもフィールドがゼロであるかのように扱うのが望ましい。CLIは,それを無視するのが望ましい。 

background image

216 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

22.8 ClassLayout : 0x0F 

表ClassLayoutは,クラス又は値型のフィールドがCLIによってどのように配置されるかを定義するた

めに使われる(通常,CLIは,クラス又は値型のために定義されるフィールドを,自由に,再配置及び/

又はそれらの間にすき間を挿入してよい。)。 

注記 根拠は次のとおりである。この機能(ClassLayout)は,管理下の値型を管理外のC言語の構造

体と全く同様に配置するために使われる。C言語の構造体と同じ配置にすることによって,配

置されたメモリブロックがあたかも管理外コードによって配置されたかのようにアクセス可能

になり,管理下の値型は管理外のコードに渡すことができるようになる。 

表ClassLayoutにある情報は,所有者クラス又は値型の{AutoLayout,SequentialLayout,ExplicitLayout}の

ためのフラグ値に依存する。 

型は,SequentialLayout又はExplicitLayoutと印付けられているなら配置をもつ。もし,継承連鎖の中の

いずれかの型が配置をもつならば,System.Object又はSystem.ValueTypeから直接の子孫となるも

のまですべての親も配置をもつ。 

注記 ここから参考情報であり規定ではない。 

配置は,継承連鎖の途中から始まってはならない。しかし,途中から“配置をもつこと”を取りやめるの

は,妥当とする。 

例えば,次の図式において,クラスAはSystem.Objectから導出され,クラスBはAから導出され,

クラスCは,Bから導出される。System.Objectは,配置をもたない。しかし,A,B及びCは,配置

つきで定義され,それは妥当とする。 

クラスE,F及びGについても同様である。クラスGは,配置をもたない。これも妥当とする。次の二

つは妥当でない場合を示す。 

左の図では,“配置をもつ連鎖”がʻ最高位ʼで始まってはいない。右の図では,“配置をもつ連鎖”に

background image

217 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

ʻ穴ʼがある。 

クラス又は値型の配置情報は,次の図に示すように,二つの表ClassLayout及びFieldLayoutに保持され

る。 

この例は,表ClassLayoutの行要素3が表TypeDefの行要素2をどのように指し示すかを示す(“MyClass”

というクラスの定義)。表FieldLayoutの行要素4〜6は,表Fieldの対応する行要素を指し示す。これは,

CLIが,“MyClass”で定義された三つのフィールドの明示的オフセットをどのように蓄えるかを示す(そ

れを所有しているクラス又は値型内の個々のフィールドに対する表FieldLayout内には,常に一つの行要素

が存在する。)。したがって,表ClassLayoutは,配置情報をもつ表TypeDefのそれらの行要素の拡張として

振る舞う。多くのクラスは配置情報をもたないから,全体的にみて,この設計はデータ空間を節約する。 

注記 参考情報終わり 

表ClassLayoutは,次の欄をもつ。 

− PackingSize(2バイト定数) 

− ClassSize(4バイト定数) 

− Parent(表TypeDefへの添字) 

表ClassLayoutの行要素は,この型を宣言している型宣言(10.2参照)の本体上に指令.pack及び.size

を置くことによって定義される。これらの指令のいずれかが省略されたときには,それに対応する値はゼ

ロとする(10.7参照)。 

ClassSizeがゼロとは,クラスのサイズがゼロだということを意味しない。それは,.size指令が定義時に

規定されていないことを意味する。その場合には,対象とする実行時プラットフォームにおける(省略時

の又は指定した)詰込みサイズと自然な整列とを考慮して,実際のサイズがフィールド型から計算される。 

注記 ここから参考情報であり規定ではない。 

1) 表ClassLayoutは,ゼロ個以上の行要素を含む。 

2) 表TypeDefにおいて,Parentは,クラス又は値型(インタフェースではない)に対応する妥当な行要

素を指さなければならない。[ERROR] 

3) Parentによって指されるクラス又は値型は,SequentialLayout又はExplicitLayoutでなければならない。

(23.1.5参照)(すなわち,AutoLayout型は,表ClassLayoutのどの行要素も所有してはならない。)

[ERROR] 

4) もしも,ParentがSequentialLayout型を指すならば,次となる。[ERROR] 

− PackingSizeは,{0,1,2,4,8,16,32,64,128}のいずれかでなければならない(0は,アプリ

ケーションが実行されるプラットフォームでの省略時の詰め込みサイズを意味する。)。 

− もしParentが値型を指すならば,ClassSizeは,1Mバイト(0x100000バイト)より小さくなければ

ならない。[ERROR]  

5) もしParentが型ExplicitLayout型を指すならば,次となる。[ERROR] 

− もしParentが値型を指すならば,ClassSizeは,1Mバイト(0x100000バイト)より少なくなければ

218 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

ならない。[ERROR] 

− PackingSizeは0でなければならない(なぜならば,各フィールドに明示的オフセットを与えること

は無意味であり,同様に,詰込みサイズについても明示的に値を指定することは無意味だからであ

る。)。[ERROR] 

6) 配置が,フィールドが重なり合う型を作成しない場合,型ExplicitLayoutが,正当性検証可能な型とな

っているかもしれないことに注意せよ。 

7) 継承連鎖の長さに沿っての配置は,上に規定された規則に従う(穴のない最高位の型から始めるなど)。

[ERROR] 

注記 参考情報終わり 

22.9 Constant : 0x0B 

表Constant(定数)は,フィールド,仮引数及び特性に対するコンパイル時の定数を蓄えるのに使われ

る。 

表Constantは,次の欄をもつ。 

− Type(型)(1バイト定数,1バイトの詰物のゼロが続く。)23.1.16を参照する。ilasmにおける《フィ

ールド初期値》の値nullrefの扱い(16.2参照)は,4バイトのゼロをValueとするELEMENT̲TYPE̲CLASS

とする。識別情報におけるELEMENT̲TYPE̲CLASSの使用とは異なり,これは,次に型トークンが続

かない。 

− Parent(親)[表Param,表Field又は表Propertyへの添字。より正確には,HasConstant符号化添字(24.2.6

参照)。] 

− Value(値)(ヒープBlobへの添字) 

自己反映によって可視ではあるが,Constantの情報が実行時の振る舞いに直接影響しないことに注意す

る(したがって,System.Enum.ToStringによって提供される機能の実装に用いられることがある。)。

コンパイラは,メタデータの移入の時,この情報をコンパイル時に調べる。しかし,定数の値そのものは,

それがもし使われたとしても,コンパイラが出力するCILストリームの中に埋め込まれる。実行時に,表

ConstantにアクセスするCIL命令は存在しない。 

親に対する表Constantの行要素は,その親のためのコンパイル時の値が規定されると常に生成される。

例は16.2を参照。 

注記 ここから参考情報であり規定ではない。 

1) Typeは,次のいずれかでなければならない。ELEMENT̲TYPE̲BOOLEAN,ELEMENT̲TYPE̲CHAR,

ELEMENT̲TYPE̲I1,ELEMENT̲TYPE̲U1,ELEMENT̲TYPE̲I2,ELEMENT̲TYPE̲U2,

ELEMENT̲TYPE̲I4,ELEMENT̲TYPE̲U4,ELEMENT̲TYPE̲I8,ELEMENT̲TYPE̲U8,

ELEMENT̲TYPE̲R4,ELEMENT̲TYPE̲R8,ELEMENT̲TYPE̲STRING又は Valueがゼロの

ELEMENT̲TYPE̲CLASS (23.1.16参照)。[ERROR] 

2) Typeは,次のいずれかであってはならない。ELEMENT̲TYPE̲I1,ELEMENT̲TYPE̲U2,

ELEMENT̲TYPE̲U4,ELEMENT̲TYPE̲U8(23.1.16参照)。[CLS] 

3) Parentは,表Field,表Property又は表Paramの有効な行要素を指さなければならない。[ERROR] 

4) Parentに関して,重複した行要素があってはならない。[ERROR] 

5) Constant.Typeは,Parentによって識別されたParam,Field 又は Propertyの宣言された型に正確に一

致しなければならない(親が列挙である場合には,その列挙の基礎となる型に正確に一致しなければ

ならない。)。[CLS] 

219 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

注記 参考情報終わり 

22.10 CustomAttribute : 0x0C 

表CustomAttribute(カスタム属性)には,次の欄がある。 

− Parent(親)[表CustomAttributeそのものを除く任意のメタ表への添字。より正確にはHasCustomAttribute

(24.2.6参照)符号化添字。] 

− Type(型)[表MethodDef又はMethodRefへの添字。より正確にはCustomAttributeType(24.2.6参照)

符号化添字。] 

− Value(値)(ヒープBlobへの添字。) 

表CustomAttributeは,カスタム属性(より正確には,規定されたカスタム属性クラスのオブジェクト。)

のインスタンス化に用いられるデータを実行時に蓄える。Typeという列は,誤解を招きかねない。これは,

実際には,構築子メソッドを指す。その構築子メソッドの所有者がそのカスタム属性の型となる。 

表CustomAttributeにおける親のための行要素は,属性.customによって生成される。これは,欄Typeの

値,及び場合によっては欄Valueの値を与える(箇条21参照)。 

注記 ここから参考情報であり規定ではない。 

バイナリ値はすべて先頭が最下位となるバイト順で蓄えられる(ただし,項目PackedLenを除く。これ

は,UTF8文字列での引き続くバイト数を数え上げるためにだけ使われる。)。 

1) CustomAttributeが全く存在しなくても正当とする。すなわち,フィールドCustomAttribute.Valueはnull

であってもよい。 

2) Parentは,表CustomAttributeそのものを除く任意のメタ表への添字とする。[ERROR] 

3) Typeは,表MethodDef又はMethodRefの妥当な行への添字でなければならない。その行は,(この情報

がインスタンスを形成するクラスに対する。)構築子メソッドでなければならない。[ERROR] 

4) Valueは,null又は非nullとなる。 

5) もしもValueが非nullならば,ヒープBlob内の'blob'の添字でなければならない。[ERROR] 

6) Value 'blob'の全体構造については,次の規則を適用する(23.3参照)。 

− Prologは,0x0001でなければならない。[ERROR] 

− 構築子メソッドにおいて宣言されたのと同じ個数のFixedArgがなければならない。[ERROR] 

− NumNamedは,ゼロ以上となる。 

− NamedArgは,正確にNumNamed個出現しなければならない。[ERROR] 

− NamedArgのそれぞれは,呼出し側からアクセス可能でなければならない。[ERROR] 

− もしNumNamed = 0ならば,CustomAttribには,それ以上の項目があってはならない。[ERROR] 

7) FixedArgの構造には次の規則を適用する(23.3参照)。 

− もしこの項目がベクタ(下限が0の1次元配列)でなければ,Elemがきっかり一つだけ存在しなけ

ればならない。[ERROR] 

− もしこの項目がベクタならば,次となる。 

− NumElemは,1以上でなければならない。[ERROR] 

− この後に,ElemがNumElem個出現しなければならない。[ERROR] 

8) Elemの構造には次の規則を適用する(23.3参照)。 

− これが単純型又は列挙(定義については23.3を参照する。)ならば,Elemは,単にその値からなる。

[ERROR] 

− これが文字列又は型ならば,Elemは,SerString ‒ PackedLen個のバイトとその後に続くUTF8文字

220 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

からなる。[ERROR] 

− これがボックス化単純値型(bool,char,float32,float64,int8,int16,int32,int64,符号なしint8,

符号なしint16,符号なしint32 又は符号なしint64。)ならば,Elemは,対応する型表示子

(ELEMENT̲TYPE̲BOOLEAN,ELEMENT̲TYPE̲CHAR,ELEMENT̲TYPE̲I1,ELEMENT̲TYPE̲U1,

ELEMENT̲TYPE̲I2,ELEMENT̲TYPE̲U2,ELEMENT̲TYPE̲I4,ELEMENT̲TYPE̲U4,

ELEMENT̲TYPE̲I8,ELEMENT̲TYPE̲U8,ELEMENT̲TYPE̲R4,又はELEMENT̲TYPE̲R8)とそ

れに続く値からなる。[ERROR] 

9) NamedArgの構造には次の規則を適用する(23.3参照)。 

− 単一バイトFIELD(0x53)又はPROPERTY(0x54)。[ERROR] 

− フィールド又は特性の型は,ELEMENT̲TYPE̲BOOLEAN,ELEMENT̲TYPE̲CHAR,

ELEMENT̲TYPE̲I1,ELEMENT̲TYPE̲U1,ELEMENT̲TYPE̲I2,ELEMENT̲TYPE̲U2,

ELEMENT̲TYPE̲I4,ELEMENT̲TYPE̲U4,ELEMENT̲TYPE̲I8,ELEMENT̲TYPE̲U8,

ELEMENT̲TYPE̲R4,ELEMENT̲TYPE̲R8,ELEMENT̲TYPE̲STRINGの一つ又は定数0x50(型

System.Typeの実引数)のいずれかとする。 

− フィールド又は特性の名前,それぞれ既に示したようにSerString ‒ PackedLen個のバイトとその後

に続くUTF8文字からなる。[ERROR] 

− FixedArg(上参照)[ERROR] 

注記 参考情報終わり 

22.11 DeclSecurity : 0x0E 

System.Security.Permissions.SecurityAttribute(第4章参照)から導出されるセキュリテ

ィ属性は,TypeDef,Method又はAssemblyに付与できる。このクラスのすべての構築子は,第1仮引数と

して値をとらなければならない。これは,それが付与される型,メソッド又はアセンブリに対する許可を

どうすべきか記述する。System.Security.Permissions.CodeAccessSecurityAttributeから導

出されるコードアクセスセキュリティ属性は,任意のセキュリティ動作をもつ。 

これらの異なるセキュリティ動作は,2バイト列挙(下参照)として表DeclSecurityにおいて符号化され

る。メソッド,型又はアセンブリの与えられたセキュリティ動作に対するすべてのセキュリティカスタム

属性は,ひとまとめに集められ,一つのSystem.Security.PermissionSetインスタンスが生成され,

ヒープBlobに蓄えられ,表DeclSecurityから参照されなければならない。 

注記 コンパイラの観点からの一般的な処理の流れは次となる。利用者は,プログラム言語に特有な

構文を用いて,その属性の構築子への呼出しというコードを生成することによって,カスタム

属性を指定する。もしも,その属性の型が 

System.Security.Permissions.SecurityAttributeから(直接又は間接に)導出され

るならば,それは,セキュリティカスタム属性であり,次のとおり(他のカスタム属性は,22.10

で記述されるメタデータの構築子を単に記録するだけで取り扱える。)特別な取り扱いを必要と

する。属性オブジェクトが構築され,それをセキュリティ許可オブジェクト

(System.Security.Permissionから導出されるオブジェクト。)に変換するメソッド

(CreatePermission)を提供する。同じセキュリティ動作をもつ与えられたメタデータ項

目に付与されるすべての許可オブジェクトは,まとめてSystem.Security.PermissionSet

に組み合わされる。この許可集合は,そのメソッドToXMLを用いてXMLにすぐ蓄えられる形

式に変換されSystem.Security.SecurityElementを生成する。最後に,メタデータに必

background image

221 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

要なXMLがセキュリティ要素のメソッドToStringを用いて生成される。 

表DeclSecurityは次の欄をもつ。 

− Action[動作(2バイト値。)] 

− Parent[親(表TypeDef,MethodDef 又は Assemblyへの添字。より正確にはHasDeclSecurity(24.2.6

参照)符号化添字。)] 

− PermissionSet[許可集合(ヒープBlobへの添字。)] 

Actionは,セキュリティ動作の2バイト表現とする(System.Security.SecurityAction,第4章

参照)。値0から0xFFは,将来の標準利用のために予約されている。値0x20から0x7F及び0x100から0x07FF

は,セキュリティ動作が理解されない又は指示されていない場合に無視されるものに使われる。値0x80

から0xFF及び0x0800から0xFFFFは,安全な操作のために動作が実装されなければならないもののため

使われる。セキュリティ動作が使えない実装では,アセンブリ,型又はメソッドへのいかなるアクセスも

許可されてはならない。 

セキュリティ動作 

注記 

振る舞いの説明 

正当な有効範囲 

Assert 

それ以上の試験を必要とせずに特定許可の要求を満たす。 

Method,Type 

Demand 

特定の許可が与えられてきた呼出し連鎖におけるすべての呼
出し側を検査する。失敗時には,SecurityException(第4
章参照)を送出する。 

Method,Type 

Deny 

それ以上検査せずに特定許可要求を拒否する。 

Method,Type 

InheritanceDemand 

クラスからの継承又は仮想メソッドを上書きするために規定
された許可が与えられる。 

Method,Type 

LinkDemand 

直接の呼出し側が指定された許可を認められているか検査す
る。不合格である場合は,SecurityException(第4章参照)
を送出する。 

Method,Type 

NonCasDemand 

現在のアセンブリが指定された許可を認められているか検査
する。そうでないと,SecurityException(第4章参照)を
送出する。 

Method,Type 

NonCasLinkDemand 

直接の呼出し側が指定された許可を認められているか検査す
る。そうでないと,SecurityException(第4章参照)を送
出する。 

Method,Type 

PrejitGrant 

実装に特化した利用のために予約する。 

Assembly 

PermitOnly 

これ以上試験をせずに,指定された以外のすべての許可を要求
に対して拒否する。 

Method,Type 

RequestMinimum 

実行に必要な最低限度の許可を規定する。 

Assembly 

RequestOptional 

省略可能な許可として与えるものを規定する。 

Assembly 

RequestRefuse 

認めない許可を規定する。 

Assembly 

注1) 規定された属性は,System.Security.Permissions.CodeAccess-SecurityAttributeから導出さ

れなければならない。 

2) 規定された属性は,System.Security.Permissions.SecurityAttributeから導出されなければなら

ないが,System.Security.Permissions.CodeAccessSecurityAttributeから導出されてはならな
い。 

Parentは,PermissionSetにおいて直列化されたセキュリティカスタム属性がその上で定義されていた

Method,Type 又はAssemblyを識別するメタデータトークンとする。 

PermissionSetは,次の形式をもつ'blob'とする。 

− ピリオドを含むバイト 

− blobにおいて符号化された属性の個数を含む圧縮Int32 

222 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

− 次をそれぞれ含む属性の配列 

− 属性の完全に修飾された型名の文字列。(文字列は,サイズを示す圧縮intとそれに続くUTF8文字

というふうに符号化される。) 

− カスタム属性への名前付き引数として符号化された特性の集合。(23.3のように,NumNamedで始

まる。) 

その許可集合には,特定のMethod,Type又はAssemblyに対するActionとともに要求された許可を含む

(Parent参照)。言い換えると,blobは,Parent上のすべての属性とその特定のActionとの符号化を含む。 

注記 この規格の第1版は,許可集合のXML符号化を規定した。実装は,後方互換性を維持するた

めにこの符号化を支持し続けるのが望ましい。 

表DeclSecurityの行要素は,親のアセンブリ(6.6参照)又は親の型若しくはメソッド(10.2参照)に対

するAction及びPermissionSetを規定する指令.permission又は指令.permissionsetを付加することによって充

足される。 

注記 ここから参考情報であり規定ではない。 

1) Actionは,規定された値だけをとらなくてはならない。[ERROR] 

2) Parentは,TypeDef,MethodDef又はAssemblyのいずれかでなければならない。すなわち,表TypeDef,

MethodDef又はAssemblyの妥当な行要素を指さなければならない。 

3) もしも,Parentが表TypeDefの行要素を指すならば,その行要素は,インタフェースを定義しないこ

とが望ましい。セキュリティシステムは,そのような親を無視する。コンパイラは,そのような許可

集合を出力しないことが望ましい。[WARNING] 

4) もしも,ParentがTypeDefを指すならば,そのビットTypeDef.Flags.HasSecurityは立っていなければな

らない。[ERROR] 

5) もしも,ParentがMethodDefを指すならば,そのビットMethodDef.Flags.HasSecurityは立っていなけ

ればならない。[ERROR] 

6) PermissionSetは,ヒープBlobにおける'blob'を指さなければならない。[ERROR] 

7) PermissionSet が指す'blob'の書式は,妥当な直列化したCLIオブジェクトグラフを表現しなければなら

ない。標準化許可すべての直列化形式は,第4章で規定する。[ERROR] 

注記 参考情報終わり 

22.12 EventMap : 0x12 

表EventMapは,次の欄をもつ。 

− Parent[親(表TypeDefへの添字。)] 

− EventList[イベント並び(表Eventへの添字。]これは,この型が所有するイベントの連続実行の先頭

を印付ける。実行は,次の小さなものへと継続する。 

− 表Eventの最終行要素。 

− 表EventMapの次の行要素のEventListを調べて見つかった,イベントの次の実行。 

EventMapの情報は,実行時の振る舞いに直接影響しないことに注意する。重要なのは,イベントが含む

メソッドのために蓄えられた情報である。 

表EventMap及びEventは,クラスに.event指令を置くことによって得られる。 

注記 ここから参考情報であり規定ではない。 

1) 表EventMapには,ゼロ個以上の行要素を含む。 

2) Parentに関して,重複した行要素があってはならない(与えられたクラスは,そのイベント並びの先

background image

223 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

頭へ一つのポインタだけをもつ。)。[ERROR] 

3) EventListに関して,重複した行要素があってはならない(異なるクラスは,表Eventにおいて行要素

を共有できない。)。[ERROR] 

注記 参考情報終わり 

22.13 Event : 0x14 

イベントは,メタデータの中では特性と同じように扱われる。すなわち,与えられたクラスで定義され

たメソッドの集まりに対して関連付けられる。add̲及びremove̲という二つのメソッドが必す(須)であ

り,省略可能なraise̲というメソッドがある。他のメソッドも許される。イベントとして一緒に集められ

たすべてのメソッドは,クラスで定義されなければならない。 

表TypeDefの行要素と,与えられたイベントを構成するメソッドの集まりとの間の関連は,三つの別々

の表に蓄えられる(特性のために使われたのと全く同様とする。)。次を参照する。 

表EventMapの第3行要素は,左の表TypeDefの第2行要素(MyClass)を指し,同時に,右の表Event

の第 4行要素を指す。それは,DocChangedと呼ばれるイベントの行要素である。この設定で,MyClass

がDocChangedと呼ばれるイベントをもつことが確かとなる。しかし,表MethodDefのどのようなメソッ

ドがまとめて集められて,イベントDocChangedに属するようになるのか?この関連は,表MethodSemantics

に含まれる。その第 2行要素は,右にあるイベントDocChangedを指すとともに,左にある表MethodDef

の第2行要素(add̲DocChangedと呼ばれるメソッド。)を指す。さらに,表MethodSemanticsの第3行要

素は,右のDocChanged及び左の表MethodDefの第3行要素(remove̲DocChangedと呼ばれるメソッド。)

を指す。色付けが示すように,MyClassにはTimedOutと呼ばれるもう一つのイベントがあり,add̲TimedOut

及びremove̲TimedOutという二つのメソッドをもつ。 

イベント表は,他の表にある行要素をひとまとめにする他はあまり役割がない。表Eventには,欄

EventFlags,Name(例 この例では DocChanged 及び TimedOut)及び EventTypeがある。さらに,表

MethodSemanticsには,指しているメソッドがadd̲,remove̲,raise̲,又はotherのうちのいずれかを記録

する欄がある。 

注記 otherは欄のフラグの一種であり,add̲,remove̲,raise̲以外の他のメソッドであることを示す。 

イベント表には,次の欄がある。 

− EventFlags(型EventAttributeの2バイトビットマスク,23.1.4参照) 

− Name(ヒープStringへの添字。) 

− EventType[イベント型(表TypeDef,TypeRef 又は TypeSpecへの添字。より正確には,TypeDefOrRef f

224 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

(24.2.6参照)符号化添字。)] 

注記 これは,イベントの型に対応する。このイベントを所有する型ではない。 

情報Eventは,実行時の振る舞いに直接影響しないことに注意する。重要なのは,イベントが含むメソ

ッドのために蓄えられた情報である。 

表EventMap及びEventは,クラス上に指令.eventを置くことによって得られる(箇条18参照)。 

注記 ここから参考情報であり規定ではない。 

1) 表Eventは,ゼロ個以上の行要素を含む。 

2) それぞれの行要素は,表EventMapにおいてただ一つの所有者行要素をもつ。[ERROR] 

3) EventFlagsは,規定された値集合だけをもつことができる(すべての組合せが正当とする。)。[ERROR] 

4) Nameは,ヒープStringにおける非空文字列を指さなければならない。[ERROR] 

5) 文字列Nameは,妥当なCLS識別子でなければならない。[CLS] 

6) EventTypeは,null又は非nullとなる。 

7) もしEventTypeが非nullならば,表TypeDef又はTypeRefの妥当な行要素を指さなければならない。

[ERROR] 

8) もしEventTypeが非nullならば,それが指す表TypeDef,TypeRef又はTypeSpecの行要素は,クラスで

なければならない(インタフェースであってはならず,値型であってもならない。)。[ERROR] 

9) それぞれの行要素について,表MethodSemanticsにおいて,一つのadd̲及び一つのremove̲行要素がな

ければならない。[ERROR] 

10) それぞれの行要素について,表MethodSemanticsにおいて,ゼロ又は一つのraise̲及びゼロ個以上の

other 行要素があり得る。[ERROR] 

注記 other行要素という表現は,欄のフラグがotherという意味と,そのメソッドがadd̲,remove̲,

raise̲以外の他のメソッドであることの二重の意味をもつ。 

11) 表TypeDefにおける与えられた行要素が所有する行要素において,Nameに関する重複があってはなら

ない。[ERROR] 

12) Nameに関して重複する行要素があってはならない。ここで,フィールドNameは,CLS衝突識別子規

則を用いて比較する。[CLS] 

注記 参考情報終わり 

22.14 ExportedType : 0x27 

表ExportedType(移出型)は,このアセンブリの他のモジュール,すなわちこのアセンブリから移出さ

れたモジュールにおいて定義されたそれぞれの型のための行要素を保持する。要するに,それは,このア

センブリが含むモジュールにおいて,公開と印付けられたすべての型のTypeDef 行要素 numbersを蓄えて

いる。 

表TypeDefにおける実際の対象となる行要素は,TypeDefId(実際は,行要素 number。)及びImplementation

(実際は,対象となる表TypeDefが保持するモジュール。)の組合せで与えられる。これがメタデータにお

いて外部トークンが出現する唯一の場合であることに注意する。すなわち,別のモジュールにおいて意味

をもつトークン値である(通常のトークン値は,現在のモジュールにおける表内への添字となる。)。 

型の完全名が,直接蓄えられる必要はない。その代わりに,途中の任意の“.”で二つの部分に分けるこ

とができる(もっとも,普通は,完全名の最後の“.”で分割される。)。“.”に先立つ部分は,TypeNamespace

として蓄えられ,“.”に続く部分はTypeNameとして蓄えられる。もしも,完全名に“.”が含まれないな

らば,TypeNamespaceは,空文字列への添字でなければならない。 

225 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

表ExportedTypeには,次の欄がある。 

− Flags(型TypeAttributeの4バイトビットマスク,23.1.15参照) 

− TypeDefId(このアセンブリにおける別のモジュールの表TypeDefへの4バイト添字。)この欄はヒント

としてだけ使われる。もし,対象の表TypeDefにおける入口が,この表の入口TypeName及び

TypeNamespaceに一致するならば,解決は成功する。しかし,一致しないならば,CLIは,目標の表

TypeDefのTypeDefIdの探索をやり直さなければならない。 

− TypeName(ヒープStringへの添字。) 

− TypeNamespace(ヒープStringへの添字。) 

− Implementation。これは,次の二つの表のいずれかへの添字[より正確には実装(24.2.6参照)符号化

添字。]となる。 

− 表File,その要素は,現在のアセンブリのどのモジュールがTypeDefを保持するかを示す。 

− 表ExportedType,その要素は,現在の入れ子の型を取り囲む型となっている。 

表ExportedTypeの行要素は,指令.class externの結果として得られる(6.7参照)。 

注記 ここから参考情報であり規定ではない。 

“完全名”という用語は,次のとおり作られた文字列を指す。すなわちTypeNamespaceが空文字列なら

ば,TypeNameを使い,そうでなければ,Typenamespace,“.”とTypeNameとを連結した文字列を使う。 

1) 表ExportedTypeは,ゼロ個以上の行要素を含む。 

2) 表ExportedTypeには,現在のモジュールで定義された型に対する要素があってはならない。アセンブ

リの中の他のモジュールで定義された型に対する要素だけとする。[ERROR] 

3) Flagsは,指定された値以外をとってはならない。[ERROR] 

4) Implementationが表Fileを指すならば,Flags.VisibilityMaskはpublicでなければならない(23.1.15

参照)。[ERROR] 

5) Implementationが表ExportedTypeを指すならば,Flags.VisibilityMaskはNestedPublicでなければな

らない(23.1.15参照)。[ERROR] 

6) TypeDefIdは,もしも非nullならば,このアセンブリにおけるいずれかのモジュールの(ただし,現在

のモジュールではない。)表TypeDefにおける妥当な行要素を指すことが望ましい。[WARNING] 

7) TypeNameは,ヒープStringにおける非空文字列を指さなければならない。[ERROR] 

8) TypeNameは,null又は非nullとなる。 

9) TypeNamespaceが非nullならば,ヒープの非空文字列を指さなければならない。[ERROR] 

10) FullNameは,妥当なCLS識別子でなければならない。[CLS] 

11) これが入れ子型ならば,TypeNamespaceが,nullであり,TypeNameが入れ子型の管理外の単純名を表

現することが望ましい。[ERROR] 

12) Implementationは,次のいずれかへの妥当な添字でなければならない。[ERROR] 

− 表File。そのファイルは,TypeDefにある対象となる型の定義を含まなければならない。 

− 現在の表ExportedTypeにおける異なる行要素。これは,現在の入れ子型を取り囲む型を識別する。 

13) FullNameは,TypeDefIdで指される表TypeDefにおける行要素に対応するFullNameと正確に一致しな

ければならない。[ERROR] 

14) 入れ子型を無視すれば,FullNameに関して行要素が重複してはならない。[ERROR] 

15) 入れ子型に対しては,TypeName及び取り囲む型に関して行要素が重複してはならない。[ERROR] 

16) 現在のアセンブリから移出された型の完全な並びは,現在の表TypeDefにおけるすべての公開型と表

background image

226 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

ExportedTypeとの連結として与えられる。ここで,“公開”とは,Flags.tdVisibilityMaskがPublic又は

NestedPublicである。この連結された表においては,FullNameに関して重複した行要素があってはな

らない(これが入れ子型ならば,重複試験に取り囲む型を追加する。)。[ERROR] 

注記 参考情報終わり 

22.15 Field : 0x04 

Fieldには,次の欄がある。 

− Flags(型Fieldattributesの2バイトビットマスク。23.1.5参照) 

− Name(ヒープStringへの添字。) 

− Signature(ヒープBlobへの添字。) 

概念的には,表Fieldの各行要素は表TypeDefのただ一つの行要素によって所有される。しかし,表Field

の行要素の所有者は表Fieldそのもののどこにも蓄えられない。次の図に示されるように,表TypeDefの各

行要素(欄FieldList)からのʻ前進ポインタʼが存在するだけに過ぎない。 

この例では,表TypeDefには1から4までの行要素がある。表TypeDefの最初の行要素は,CLIによって

自動的に挿入される擬似的な型に対応する。それは,大域変数に対応する表Fieldにおける行要素を表記

するのに使われる。表Fieldには,1から6までの行要素がある。型1(モジュールのための擬似的な型。)

は,表Fieldの行要素1及び2を所有する。型2は,そのFieldListが表Fieldの行要素3を指すにもかかわ

らず,表Fieldの行要素をなんら所有しない。型3は,表Fieldの3〜5の行要素を所有する。型4は,表

Fieldの行要素6を所有する(図の中の次のポインタは,各表中の次の空き行要素を示す。)。したがって,

表Fieldにおいては,行要素1及び2は型1(大域変数)に属し,行要素3〜5は型3に属し,行要素6は

型4に属す。 

表Fieldの各行要素は,最上位の指令.field(5.10参照)又は型の内部の指令.field(10.2参照)から得ら

れる。例については,14.5を参照する。 

注記 ここから参考情報であり規定ではない。 

1) 表Fieldには,ゼロ個以上の行要素がある。 

2) 各行要素には,表TypeDefの所有者行要素が一つだけ存在しなければならない。[ERROR] 

3) 表TypeDefの所有者行要素は,インタフェースであってはならない。[CLS] 

4) Flagsは,指定されたものしか立ってはならない。[ERROR] 

5) Flagsの下位フィールドFieldAccessMaskは,正確に,CompilerControlled,Private,

FamANDAssem,Assembly,Family,FamORAssem又はPublicのうちの一つでなければならない

(23.1.5参照)。[ERROR] 

6) Flagsは,Literal又はInitOnly(両方ではない)の0又は1を設定する(23.1.5参照)。[ERROR] 

7) もしFlags.Literal = 1ならば,Flags.Staticもまた,1でなければならない(23.1.5参照)。[ERROR] 

8) もしFlags.RTSpecialName = 1ならば,Flags.SpecialNameもまた1でなければならない(23.1.5参照)。

[ERROR] 

227 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

9) もしFlags.HasFieldMarshal = 1ならば,この行要素は,表FieldMarshalにおいて正確に一つの行要素

を所有しなければならない(23.1.5参照)。[ERROR] 

10) もしFlags.HasDefault = 1ならば,表Constantにおいて正確に一つの行要素を所有しなければならない

(23.1.5参照)。[ERROR] 

11) もしFlags.HasFieldRVA = 1ならば,表Fieldʼs RVAにおいて正確に一つの行要素を所有しなければなら

ない(23.1.5参照)。[ERROR] 

12) Nameは,ヒープStringにおける非空文字列を指さなければならない。[ERROR] 

13) 文字列Nameは,妥当なCLS識別子でなければならない。[CLS] 

14) Signatureは,ヒープBlobにおける妥当なフィールド識別情報を指さなければならない。[ERROR] 

15) もしFlags. CompilerControlled = 1(23.1.5参照)ならば,この行要素は,重複検査において全く無視

される。 

16) もし,このフィールドが<Module>と呼ばれる内部生成型ならば,それは,このフィールドが(一般に

大域変数と呼ばれる)モジュール有効範囲で定義されることを表記する。この場合には,次となる。 

− Flags.Staticは,1でなければならない。[ERROR] 

− 下位フィールドFlags.MemberAccessMaskは,Public,CompilerControlled又はPrivateの

うちの一つでなければならない(23.1.5参照)。[ERROR] 

− モジュール有効範囲フィールドは,許されない。[CLS] 

17) 表Fieldにおいては,owner+Name+Signatureに関する重複した行要素があってはならない。ここで,

所有者とは表TypeDefにおける所有する行要素とする(しかし,もしFlags.CompilerControlled = 1なら

ば,この行要素は重複検査から完全に排除されることに注意する。)。[ERROR] 

18) 表Fieldは,owner+Nameに関して重複してはならない。ここで,フィールドNameは,CLS識別子衝

突規則を用いて比較する。したがって,例えば,"int i"及び"float i"は,CLS重複と考える(し

かし,もしFlags.CompilerControlled = 1ならば,上の項目17)注意でも示したように,この行要素は

重複検査から完全に除外されることに注意する。)。[CLS] 

19) これが列挙のフィールドであり,文字列Name= "value̲̲"ならば,次となる。 

a) RTSpecialNameは,1でなければならない。[ERROR] 

b) 表TypeDefにおける所有者行要素は,System.Enumから直接導出されなければならない。[ERROR] 

c) 表TypeDefには,他のインスタンスフィールドがあってはならない。[CLS] 

d) そのSignatureは,次のいずれかでなければならない(23.1.16参照)。[CLS] 

− ELEMENT̲TYPE̲U1 

− ELEMENT̲TYPE̲I2 

− ELEMENT̲TYPE̲I4 

− ELEMENT̲TYPE̲I8 

20) そのSignatureは,整数型でなければならない。 

注記 参考情報終わり 

22.16 FieldLayout : 0x10 

表FieldLayoutには,次の欄がある。 

− Offset(4バイト定数。) 

− Field(表Fieldへの添字。) 

型におけるフィールドは,すべて識別情報によって定義されることに注意する。型インスタンス(すな

228 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

わち,オブジェクト。)がCLIによって配置されるときには,各フィールドは,次の4種類のうちのいず

れかとなる。 

− Scalar  int32のような任意の組込み型のメンバに対する。フィールドのサイズは,その本質のサイ

ズによって与えられる。それは,1バイト〜8バイトの間で変化する。 

− ObjectRef ELEMENT̲TYPE̲CLASS,ELEMENT̲TYPE̲STRING,ELEMENT̲TYPE̲OBJECT, 

ELEMENT̲TYPE̲ARRAY,ELEMENT̲TYPE̲SZARRAYに対する。 

− Pointer ELEMENT̲TYPE̲PTR,ELEMENT̲TYPE̲FNPTRに対する。 

− VAlueType ELEMENT̲TYPE̲VALUETYPEに対する。この値型のインスタンスは,実際にはこのオブ

ジェクト内に配置されるから,フィールドのサイズが値型のサイズとなる。 

明示的な構造配置を指定するメタデータは,あるプラットフォームでは妥当となるが,他のプラットフ

ォームでは妥当でないことがありえることに注意する。その理由は,ここで指定する規則が特定のプラッ

トフォームの配置規則に依存するからとする。 

表FieldLayoutの行要素は,親フィールドのための指令.fieldがフィールドオフセットを指定すること

によって生成される(箇条16参照)。 

注記 ここから参考情報であり規定ではない。 

1) 表FieldLayoutには,ゼロ個以上の行要素がある。 

2) 表FieldLayoutの行要素によって記述されるフィールドをもつ型では,Flags.ExplicitLayout(23.1.15参

照)が設定されていなければならない。[ERROR] 

3) Offsetは,ゼロ以上でなければならない。[ERROR] 

4) Fieldは,表Fieldの妥当な行要素を指さなければならない。[ERROR] 

5) 表Fieldの行要素のためのFlags.Staticは,非静的(すなわち,0。)でなければならない。[ERROR] 

6) 与えられた型によって所有される行要素の間では,Fieldに関して重複があってはならない。すなわち,

ある型の与えられたフィールドに,二つのオフセットが与えられてはならない。[ERROR] 

7) 種類がObjectRefのフィールドは,それぞれ型の内部で自然に配置されなければならない。[ERROR] 

8) 与えられた型によって所有される行要素の間では,それらが型ObjectRefでない限り,複数の行要素が

同じOffsetの値をとっても正当とする(例えば,C言語の共用体に用いられる。)。ObjectRefと値型と

は,同じオフセットをとることはできない。[ERROR] 

9) 明示的配置型のすべてのフィールドには,オフセットが与えられなければならない。すなわちすべて

のフィールドには,表FieldLayoutに行要素がある。[ERROR] 

注記 参考情報終わり 

22.17 FieldMarshal : 0x0D 

表FieldMarshalには,二つの欄がある。これは,表Field又はParamにある既存の行要素を,ディスパ

ッチによって管理外コードを呼ぶとき,又は,管理外コードから呼ばれるとき,そのフィールド又は仮引

数(0番目の仮引数としてメソッドからの戻りを含むのを常とする。)をどのように組み換えるのが望まし

いかを定義するヒープBlobにおける情報にʻ結び付けるʼ。 

情報FieldMarshalは,管理外コードとの操作を調停するコード経路によってだけ使用されることに注意

する。このような経路を実行するために,ほとんどのプラットフォームにおいて,呼出し側は,強化され

たセキュリティ許可でインストールされる。管理外コードを呼び出すと,CLIが検査できる領域外に位置

される。すなわち,型体系に違反しないものと信頼する。 

表FieldMarshalには,次の欄がある。 

229 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

− Parent[表Field又はParamへの添字。より正確には,HasFieldMarshal (24.2.6参照)符号化添字。] 

− NativeType(ヒープBlobへの添字。) 

ʻblob'の詳細な形式については,23.4を参照する。 

表FieldMarshalの行要素は,親フィールドのための指令.fieldが属性.marshallを指定したときに生

成される(16.1参照)。 

注記 ここから参考情報であり規定ではない。 

1) 表FieldMarshalには,ゼロ個以上の行要素がある。 

2) Parentは,表Field又はParamにおける妥当な行要素を指さなければならない(Parentの値は,いず

れの表を参照しているかを示すように符号化されている。)。[ERROR] 

3) NativeTypeは,ヒープBlobにおける非nullの'blob'を指さなければならない。[ERROR] 

4) どの二つの行要素も同じ親を指すことはできない。言い換えれば,Parentの値が表Field又はParam

のうちのどれを参照するか復号化された後は,どの二つの行要素も表Field又は表Paramにおける同

一の行要素を指すことはできない。[ERROR] 

5) 'blob' MarshalSpecには,次の試験が適用される(23.4参照)。 

a) NativeIntrinsicは,その生成規則で定められた定数値の一つでなければならない。[ERROR] 

b) NativeIntrinsicの値がARRAYならば,ArrayElemTypeは,その生成規則で定められた定数値の一つで

なければならない。[ERROR] 

c) NativeIntrinsicの値がARRAYならば,ParamNumはゼロであり得る。[ERROR] 

d) NativeIntrinsicの値がARRAYならば,ParamNum< 0であってはならない。 

e) NativeIntrinsicの値がARRAYであり,しかもParamNum > 0ならば,Parentは,表Fieldではなく表

Paramにおける行要素を指さなければならない。[ERROR] 

f) NativeIntrinsicの値がARRAYであり,しかもParamNum > 0ならば,親のParamがメンバである

MethodDef(又は,呼出しVARARGである場合ならば,MethodRef。)に与えられる仮引数の個数を

超えてはならない。[ERROR] 

g) NativeIntrinsicの値がARRAYならば,ElemMult >= 1でなければならない。[ERROR] 

h) NativeIntrinsicの値がARRAYであり,しかもElemMult != 1ならば,それは,おそらく間違いなので,

警告を発しなければならない。[WARNING] 

i) 

NativeIntrinsicの値がARRAYであり,しかもParamNum == 0ならば,NumElem >= 1でなければなら

ない。[ERROR] 

j) NativeIntrinsicの値がARRAYであり,しかもParamNum != 0ならば,それは,おそらく間違いなの

で,警告を発しなければならない。[WARNING] 

注記 参考情報終わり 

22.18 FieldRVA : 0x1D 

表FieldRVAには,次の欄がある。 

− RVA(4バイト定数。) 

− Field(表Fieldへの添字。) 

概念的には,表FieldRVAの各行要素は,表Fieldの正確に一つの行要素の拡張となっており,イメージ

ファイルの中でこのフィールドの初期値が蓄えられているRVA(相対仮想アドレス)を記録する。 

表FieldRVAの行要素は,省略可能なデータ用のラベルを指定した静的親フィールドのそれぞれに対して

生成される(箇条16参照)。欄RVAは,PEファイルのデータの相対仮想アドレスとなる(16.3参照)。 

230 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

注記 ここから参考情報であり規定ではない。 

1) RVAは,ゼロであってはならない。[ERROR] 

2) RVAは,現在のモジュールの(メタデータ領域ではなく)データ領域を指さなければならない。[ERROR] 

3) Fieldは,表Fieldの妥当な行要素を指さなければならない。[ERROR] 

4) RVAをもつフィールドは,どれも,(クラスやインタフェースではなく)値型でなければならない。

さらに,それには,非公開フィールドがあってはならない(同様に,それ自体が値型のそのフィール

ドのいずれも非公開フィールドであってはならない。この条件のいずれかが成り立たないならば,コ

ードは,その大域静的をオーバレイして,その非公開フィールドをアクセスできる。)。さらに,その

値型のフィールドはどれも(ヒープGCへの)オブジェクト参照であってはならない。[ERROR] 

5) 二つのRVA基盤フィールドが上の条件を満たすならば,二つの値型にまたがるメモリ領域は,それ以

上の制約なしに,重なってよい。これは,追加的規則ではない。重複したRVA基盤フィールドに関す

る位置を明確にするだけである。 

注記 参考情報終わり 

22.19 File : 0x26 

表Fileには,次の欄がある。 

− Flags(型FileAttributesの4バイトビットマスク,23.1.6参照) 

− Name(ヒープStringへの添字。) 

− HashValue(ヒープBlobへの添字。) 

表Fileの行要素は,アセンブリにおける指令.fileによって得られる(6.2.3参照)。 

注記 ここから参考情報であり規定ではない。 

1) Flags は,指定された値しかとってはならない(すべての組合せが妥当となる。)。[ERROR] 

2) Nameは,ヒープStringにある非空文字列を指さなければならない。“ファイル名”.“拡張子”という

形式でなければならない(例 “foo.dll”,しかし,“c:¥utils¥foo.dll”ではない。)。[ERROR] 

3) HashValueは,ヒープBlobにある非空'blob'を指さなければならない。[ERROR] 

4) Nameの値が同じ,重複した行要素があってはならない。[ERROR] 

5) このモジュールが表Assemblyにある行要素を含むならば,(すなわち,このモジュールが“目録をもつ”

ならば)このモジュールの表Fileには 行要素が存在してはならない,すなわち,自己参照があって

はならない。[ERROR] 

6) 表Fileが空ならば,これは,定義によって,単一ファイルアセンブリとなる。この場合,表ExportedType

は空が望ましい。[WARNING] 

注記 参考情報終わり 

22.20 GenericParam : 0x2A 

表GenericParamは,次の四つの欄がある。 

− Number(左から右へとゼロから番号付けした総称仮引数の2バイト添字) 

− Flags[型GenericParamAttributes(23.1.7参照)の2バイトビットマスク] 

− Owner(この総称仮引数に適用する型又はメソッドを規定する表TypeDef又はMethodDefへの添字。

具体的には,TypeOrMethodDef符号化添字とする。) 

− Name(総称仮引数の名前を与えるStringヒープへの非null添字。これは純粋に記述的であり,ソー

ス言語コンパイラ及び自己反映によってだけ使われる。) 

表GenericParamは,総称型定義及び総称メソッド定義に用いられる総称仮引数を蓄える。この総称仮引

231 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

数は,制約づけることもできれば(すなわち,総称実引数は,あるクラスを拡張する,及び/又はあるイ

ンタフェースを実装する),無制約にもできる。(そのような制約は,表GenericParamConstraintに蓄えら

れる。) 

概念的には,表GenericParamの各欄は,表TypeDef又はMethodDefのただ一つの欄によって,所有され

る。 

例 

.class Dict̀2<([mscorlib]System.IComparable) K, V> 

クラスDictの総称仮引数Kは,System.IComparableを実装するように制約される。 

.method static void ReverseArray<T>(!!0[] 'array') 

総称メソッドReverseArrayの総称仮引数Tには,制約がない。 

注記 ここから参考情報であり規定ではない。 

1) 表GenericParamは,ゼロ個以上の行を含んでよい。 

2) 各行は,表TypeDef又はMethodDefにおける,ただ唯一の所有者行をもたなければならない。(すなわ

ち,共有してはならない。)[ERROR] 

3) あらゆる総称型は,その総称仮引数の表において,一つの行を所有しなければならない。[ERROR] 

4) あらゆる総称メソッドは,総称仮引数の各々のために,表GenericParamにおいて一つの行を所有しな

ければならない。[ERROR] 

フラグについては,次とする。 

− 値Covariant又はContravariantを保持できるが,それは,所有者行が総称インタフェース又は総称委

譲クラスに対応する場合だけとする。[ERROR] 

− そうでなければ,値NonVariantを保持しなければならない。(すなわち,所有者が,非委譲クラス,

値型,又は総称メソッドとする。) 

もしも,Flags == Covariantならば,対応する総称仮引数は,次の型定義に出現できる。[ERROR] 

− メソッドの結果型 

− 継承インタフェースへの総称仮引数 

もしも,Flags == Contravariantならば,対応する総称仮引数は,実引数又はメソッドとしてだけ型定義

に出現できる。[ERROR] 

Numberは,ゼロ以上かつ所有者の型又はメソッドでの総称仮引数の個数より少ない値をもたなければな

らない。[ERROR] 

同じメソッドによって所有される表GenericParamの引き続く行は,Number値の昇順に並べなければな

らない。Numberの列には,すき間があってはならない。[ERROR] 

注記 根拠は次のとおりである。そうでなければ,自己反映の出力を完全に利用することができない。 

Owner+Nameに基づいた行は重複があってはならない。[ERROR](22.15参照) 

注記 参考情報終わり 

22.21 GenericParamConstraint : 0x2C 

表GenericParamConstraintは,次の欄をもつ。 

− Owner(この行が参照する総称仮引数を指定する表GenericParamへの添字) 

− Constraint[表TypeDef,TypeRef又はTypeSpecへの添字であり,この総称仮引数が導出されるように

制約を受けているクラスを指定するか,又は,この総称仮引数が実装するように制約を受けているイ

232 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

ンタフェースを指定する。より詳しくは,添字がコード化されたTypeDefOrRef(24.2.6)を参照せよ。] 

表GenericParamConstraint は,総称仮引数ごとに制約を記録する。総称仮引数は,あるクラスから導出

されるという制約を受けることができる。総称仮引数は,あるインタフェースを実装するという制約を受

けることができる。 

概念的には,表GenericParamConstraintの各行は,表GenericParamの行によってʻ所有ʼされる。 

表GenericParamConstraintの行の中で与えられたOwnerの行は,すべてそれぞれ異なる制約を参照する。 

もしもConstraint がTypeRef to System.ValueTypeへのTypeRefならば,制約型がSystem.ValueType

でなければならないか,又はその下位型でなければならないことを意味することに注意せよ。しかし,

System.ValueTypeそのものは参照型なので,この機構自体が,型が非参照型であることを保証するわ

けではない。 

注記 ここから参考情報であり規定ではない。 

1) 表GenericParamConstraintは,ゼロ行以上の行までを含むことができる。 

2) 表GenericParam において,各行は,所有者(Owner)行を必ず一つだけもつ(すなわち行の共有はな

い。)[ERROR] 

3) 表GenericParamの各行は,その総称仮引数のもつ制約に対する表GenericParamConstraintの別の行を

“所有”しなければならない。[ERROR] 

4) 表GenericParamの与えられた行によって所有される表GenericParamConstraint のすべての行は,(行

の)連続した領域を形成しなければならない。[ERROR] 

5) (表GenericParam における行に対応する)総称仮引数は,クラス制約に対応する表

GenericParamConstraintのゼロ個又は1個の行をもたなければならない。[ERROR] 

6) (表GenericParamにおける行に対応する)総称仮引数は,インタフェース制約に対応する表

GenericParamConstraintのゼロ個以上の行をもたなければならない。[ERROR] 

7) Owner+Constraintに基づいた重複行があってはならない。[ERROR] 

8) Constraint は,System.Voidを参照してはならない。[ERROR] 

注記 参考情報終わり 

22.22 ImplMap : 0x1C 

表ImplMapは,ディスパッチPInvokeを用いて管理下コードから到達可能な管理外メソッドについての

情報を保持する。 

表ImplMapの各行要素は,表Methodの行要素(MemberForwarded)に管理外DLL(ImportScope)のル

ーチンの名前(ImportName)を関連付ける。 

注記 典型的な例は次となる。表MethodのN番目の行要素に蓄えられた管理下メソッド(すなわち,

MemberForwardedが値Nをもつ)に,“kernel32”(文字列は,ImportScopeによって指される。)

と呼ばれるDLLにある“GetEnvironmentVariable”と呼ばれるルーチン(文字列は,

ImportNameによって指される。)を関連付ける。CLIは,N番目の管理下メソッドへの呼出し

を横取りして,その代わりに,“kernel32.dll”における“GetEnvironmentVariable”と呼ば

れる管理外ルーチンへの呼出しとして(必要に応じて,実引数の組換えを含めて)送る。 

CLIは,DLLから移出されるフィールドへのアクセスに対してこの機構を与えない。メソッドに対して

だけである。 

表ImplMapには,次の欄がある。 

− MappingFlags(型PinvokeAttributes用の2バイトビットマスク,23.1.7参照) 

233 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

− MemberForwarded(表Field又はMethodDefへの添字。より正確には,MemberForwarded符号化添字。)

しかし,Fieldの移出は与えられていないから,表MethodDefだけを指す。 

− ImportName(ヒープStringへの添字。) 

− ImportScope(表ModuleRefへの添字。) 

表ImplMapの行要素は,MappingFlags,ImportName及びImportScopeを指定する相互運用属

性.pinvokeimplとともに定義される親メソッド(15.5参照)ごとに与えられる。例については,15.5

を参照。 

注記 ここから参考情報であり規定ではない。 

1) 表ImplMapには,ゼロ個以上の行要素がある。 

2) MappingFlagsは,指定された値だけを1にすることができる。[ERROR] 

3) MemberForwardedは,表MethodDefの妥当な行要素を指さなければならない。[ERROR] 

4) MemberForwardedによって指される表MethodDefの行要素のMappingFlags.CharSetMask(23.1.7参照)

は,ビット集合CharSetAnsi,CharSetUnicode,又はCharSetAutoというビットだけ1にする

ことができる。(どれも1になっていないと,省略時は,CharSetNotSpecが1になる。)。[ERROR] 

5) ImportNameは,ヒープStringにある非空文字列を指さなければならない。[ERROR] 

6) ImportScopeは,表ModuleRefの妥当な行要素を指さなければならない。[ERROR] 

7) MemberForwardedによって指される表MethodDefの行要素は,そのFlags.PinvokeImpl = 1及び 

Flags.Static = 1でなければならない。[ERROR] 

注記 参考情報終わり 

22.23 InterfaceImpl : 0x09 

表InterfaceImplには,次の欄がある。 

− Class(表TypeDefへの添字。) 

− Interface(表TypeDef,TypeRef又はTypeSpecへの添字。より正確には,TypeDefOrRef(24.2.6)符号化

添字。) 

表InterfaceImplは,型が実装するインタフェースを記録する。概念的には,表InterfaceImplの各行要素

は,ClassがInterfaceを実装することを示す。 

注記 ここから参考情報であり規定ではない。 

1) 表InterfaceImplには,ゼロ個以上の行要素がある。 

2) Classは,非nullでなければならない。[ERROR] 

3) Classが非nullならば,次となる。 

a) Classは,表TypeDefの妥当な行要素を指さなければならない。[ERROR] 

b) Interfaceは,表TypeDef又はTypeRefの妥当な行要素を指さなければならない。[ERROR] 

c) Interfaceによって指される表TypeDef,TypeRef又はTypeSpecの行要素は,インタフェースでなけれ

ばならず,クラス又は値型であってはならない。[ERROR] 

4) 表InterfaceImplには,非nullClass及びInterface値に関して重複がないことが望ましい。[WARNING] 

5) Classについて同じ値の複数の行要素があり得る(クラスは複数のインタフェースを実装できる。)。 

6) Interfaceについて同じ値の複数の行要素があり得る(複数のクラスが同一のインタフェースを実装で

きる。)。 

注記 参考情報終わり 

22.24 ManifestResource : 0x28 

234 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

表ManifestResourceには,次の欄がある。 

− Offset(4バイト定数。) 

− Flags(型ManifestResourceAttributes用の4バイトビットマスク,23.1.9参照) 

− Name(ヒープStringへの添字。) 

− Implementation(表Field又は表AssemblyRefへの添字又はnull。より正確にはImplementation符号化添

字。) 

Offsetは,そこから,この資源のレコードが始まる,参照されたファイル内のバイトオフセットを指定

する。Implementationは,どのファイルがこの資源をもつかを指定する。表の行要素は,アセンブリ上の

指令.mresourceによって得られる。(6.2.2参照) 

注記 ここから参考情報であり規定ではない。 

1) 表ManifestResourceには,ゼロ個以上の行要素がある。 

2) Offsetは,対象とするファイルの妥当なオフセットでなければならない。それは,ヘッダCORにおけ

る資源入口から計算する。[ERROR] 

3) Flagsは,指定された値しかとってはならない。[ERROR] 

4) Flagsの下位フィールドVisibilityMask(23.1.9参照)は,Public又は Privateのいずれかでなけれ

ばならない。[ERROR] 

5) Nameは,ヒープStringにある非空文字列を指さなければならない。[ERROR] 

6) Implementationは,null又は非nullとする(nullは,資源が現在のファイルに蓄えられていることを意

味する。)。 

7) Implementationがnullならば,Offsetは,CLIヘッダの資源入口から計算した妥当なオフセットとする。

[ERROR] 

8) Implementationが非nullならば,それは,表File 又は AssemblyRefの妥当な行要素を指さなければな

らない。[ERROR] 

9) Nameに関して,重複した行要素があってはならない。[ERROR] 

10) 資源が表Fileへの添字ならば,Offsetはゼロでなければならない。[ERROR] 

注記 参考情報終わり 

22.25 MemberRef : 0x0A 

表MemberRefでは,あるクラスのフィールド及びメソッドへの,ʻFieldRefʼ及びʻMethodRefʼとして

知られる2種類の参照,が組み合わされる。表MemberRefには,次の欄がある。 

− Class(表TypeRef,ModuleRef,MethodDef,TypeSpec又はTypeDefへの添字。より正確には 

MemberRefParent符号化添字。) 

− Name(ヒープStringへの添字。) 

− Signature(ヒープBlobへの添字。) 

CILコードにおいて,他のモジュール又はアセンブリで定義されたメソッド又はフィールドへの参照が

作られると,それに対する表MemberRefの要素が作られる(さらに,たとえ,同一のモジュールでcallsite

として定義されている場合でも,呼出し情報がVARARGのメソッドへの呼出しには,それに対する表

MemberRefの要素が作られる。)。 

注記 ここから参考情報であり規定ではない。 

1) Classが指すのは次のうちのいずれかでなければならない。[ERROR] 

a) メンバを定義するクラスが他のモジュールで定義されているならば,字句TypeRef。 

235 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

注記 この同じモジュールでメンバが定義されるときに,字句TypeRefを用いるのは,普通では

ないが,妥当とする。字句TypeDefをその代わりに用いることができる。 

b) メンバが同じアセンブリの他のモジュールで,大域関数又は変数として定義されているならば,字

句ModuleRef。 

c) このモジュールで定義される可変個引数メソッドのためのcallsite呼出し情報を与えるために使わ

れるときは,字句MethodDef。Nameは,対応するMethodDefの行要素のNameに対応付けられなけ

ればならない。Signatureは,対象メソッド定義のSignatureに対応付けられなければならない。

[ERROR]  

d) メンバが構築された型のメンバならば,字句TypeSpec。 

2) Classは,nullであってはならない(これは,大域関数又は変数への未解決の参照となるから。)。

[ERROR] 

3) Nameは,ヒープStringにある非空文字列を指さなければならない。[ERROR] 

4) Name文字列は,妥当なCLS識別子でなければならない。[CLS] 

5) Signatureは,ヒープBlobにおける妥当なフィールド又はメソッド識別情報を指さなければならない。

特に,それは,次のいずれかのʻ呼出し規約ʼの一つを正確に埋め込まなければならない。[ERROR] 

a) DEFAULT (0x0) 

b) VARARG (0x5) 

c) FIELD (0x6) 

d) GENERIC (0x10) 

6) 表MemberRef には,重複があってはならない。ここで,重複した行要素とは,同じClass,Name 及

び Signatureをもつものをいう。[WARNING] 

7) Signatureは,VARARG (0x5) 呼出し規約をもってはならない。[CLS] 

8) CLS衝突識別子規則を用いてNameフィールドを比較したときに,重複する行要素があってはならな

い。[特に,返却値の型,及び仮引数がELEMENT̲TYPE̲BYREF(23.1.16参照)で印づけられている

かどうかがCLSでは無視されることに注意する。例えば,int foo()及びdouble foo()は,CLS

規則によって重複行要素をもたらす。同様に,void bar(int i)及びvoid bar(int& i)もまた,

CLS規則によって重複行要素をもたらす。][CLS] 

9) Class及びNameが一つのフィールドとして解決されるならば,そのフィールドは,下位フィールド

Flags.FieldAccessMaskにおいて値CompilerControlled(23.1.5参照)をとってはならない。[ERROR] 

10) Class及びNameが一つのメソッドとして解決されるならば,そのメソッドは,下位フィールド

Flags.MemberAccessMask(23.1.10参照)において値CompilerControlledをとってはならない。

[ERROR] 

11) MemberRefの定義を含む型は,インスタンス化された型を表現するTypeSpecでなければならない。 

注記 参考情報終わり 

22.26 MethodDef : 0x06 

表MethodDefには,次の欄がある。 

− RVA(4バイト定数) 

− ImplFlags(型MethodImplAttributes用の2バイトビットマスク,23.1.10参照) 

− Flags(型MethodAttribute用の2バイトビットマスク,23.1.10参照) 

− Name(ヒープStringへの添字) 

236 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

− Signature(ヒープBlobへの添字) 

− ParamList(表Paramへの添字)これは,このメソッドが所有する仮引数の連続実行の最初を印付ける。

実行は,次のいずれか小さい方へと継続する。 

− 表Paramの最終行要素。 

− 表MethodDefの次の行要素のParamListを検査して発見した仮引数の次の実行。 

概念的には,表MethodDefのすべての行要素は,表TypeDefのただ一つの行要素によって所有される。 

表MethodDefの行要素は,指令.methodから得られる(箇条15参照)。欄RVAは,PEファイルのため

のイメージが放出されたときに計算され,メソッド本体のCOR̲ILMETHOD構造を指す(25.4参照)。 

注記 SignatureがGENERIC (0x10)ならば,総称実引数は,表GenericParam(22.20)に記述される。 

注記 ここから参考情報であり規定ではない。 

1) 表MethodDefには,ゼロ個以上の行要素がある。 

2) それぞれの行要素は,表TypeDefにおいてただ一つの所有者行要素をもたなければならない。[ERROR] 

3) ImplFlagsは,指定された値しかとってはならない。[ERROR] 

4) Flagsは,指定された値しかとってはならない。[ERROR] 

5) 名前が.ctorであり,かつ,メソッドがSpecialNameで印付けられていれば,表GenericParamにお

いて,このMethodDefを所有者としてもつ行があってはならない。[ERROR] 

6) Flagsの下位フィールドMemberAccessMask(23.1.10参照)では,CompilerControlled,Private,

FamANDAssem,Assem,Family,FamORAssem 又は Publicのうちのいずれか一つを保持しなけ

ればならない。[ERROR] 

7) Flagsにおける次の組合せビット設定は,不当とする。[ERROR] 

a) Static | Final 

b) Static | Virtual 

c) Static | NewSlot 

d) Final | Abstract 

e) Abstract | PinvokeImpl 

f) 

CompilerControlled | SpecialName 

g) CompilerControlled | RTSpecialName 

8) 抽象メソッドは,仮想でなければならない。したがって,Flags.Abstract = 1ならば,Flags.Virtualもま

た1でなければならない。[ERROR] 

9) Flags.RTSpecialName = 1ならば,Flags.SpecialNameもまた1でなければならない。[ERROR] 

10) Flags.HasSecurity = 1ならば,少なくとも次の条件の一つが真でなければならない。[ERROR] 

− このメソッドは,表DeclSecurityにおいて少なくとも一つの行要素を所有する。 

− このメソッドは,SuppressUnmanagedCodeSecurityAttributeと呼ばれるカスタム属性をもつ。 

11) このメソッドが表DeclSecurityにおいて一つ(又は複数の)行要素を所有するならば,Flags.HasSecurity

は1でなければならない。[ERROR] 

12) このメソッドがSuppressUnmanagedCodeSecurityAttributeと呼ばれるカスタム属性をもつならば,

Flags.HasSecurityは1でなければならない。[ERROR] 

13) メソッドは,DynamicSecurityMethodAttributeと呼ばれるカスタム属性をもつことができるが,これは,

そのFlags.HasSecurityの値になんら影響しない。 

14) Nameは,ヒープStringにある非空文字列を指さなければならない。[ERROR] 

237 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

15) インタフェースは,インスタンス構築子をもつことはできない。したがって,このメソッドがインタ

フェースによって所有されているならば,Nameは.ctorであってはならない。[ERROR] 

16) インタフェースは,(静的又はインスタンスメソッドではなく)仮想メソッドだけを所有できる。した

がって,このメソッドがインタフェースによって所有されているならば,Flags.Staticは0でなければ

ならない。[ERROR] 

17) Name文字列は,妥当なCLS識別子でなければならない(Flags.RTSpecialNameが設定されていない限

り,例えば,.cctorは妥当とする。)。[CLS] 

18) Signatureは,ヒープBlobにある妥当なメソッド識別情報を指さなければならない。[ERROR] 

19) Flags.CompilerControlled = 1ならば,この行要素は,重複試験において完全に無視される。 

20) このメソッドの所有者が,<Module>と呼ばれる内部的に生成された型ならば,それは,このメソッ

ドがモジュール有効範囲で定義されることを表記する。 

注記 C++では,このメソッドは,globalと呼ばれ,宣言された点から以降は,そのコンパイル

対象(compiland)の内部でだけ参照できる。この場合,次となる。 

a) Flags.Staticは,1でなければならない。[ERROR] 

b) Flags.Abstractは,0でなければならない。[ERROR] 

c) Flags.Virtualは,0でなければならない。[ERROR] 

d) 下位フィールドFlags.MemberAccessMaskは,CompilerControlled,Public又はPrivateの

うちの一つでなければならない。[ERROR] 

e) モジュール有効範囲メソッドは,許されない。[CLS] 

21) 識別性をもたない値型が,(ボックス化されない限り)同期メソッドをもつことは意味がない。したが

って,このメソッドの所有者が値型ならば,メソッドは同期できない。すなわち,ImplFlags.Synchronized

は,0でなければならない。[ERROR] 

22) owner+Name+Signatureに関して(ここで,ownerは,表TypeDefにおける所有者行要素を指す。)表

MethodDefには,重複があってはならない(しかし,Flags.CompilerControlled = 1ならば,この行要素

は,重複試験から完全に排除されることに注意する。)。[ERROR] 

23) owner+Name+Signatureに関して(ここで,フィールドNameは,CLS衝突識別子規則を用いて比較さ

れ,識別情報で定義される型は異ならなければならない。)表MethodDefには,重複があってはならな

い。例えば,"int i"及び"float i"は,CLS重複と考えられる。メソッドの返却型は無視される

(ただし,Flags.CompilerControlled = 1ならば,この行要素は重複検査の対象から完全に外される。)。

[CLS] 

24) FlagsでFinal,NewSlot又はStrictが1ならば,Flags.Virtualも1でなければならない。[ERROR] 

25) Flags.PInvokeImplが1ならば,Flags.Virtualは,0でなければならない。[ERROR] 

26) Flags.Abstract != 1ならば,次のうちの正確に一つも真でなければならない。[ERROR] 

− RVA != 0 

− Flags.PInvokeImpl = 1 

− ImplFlags.Runtime = 1 

27) メソッドがCompilerControlledならば,RVAがゼロであってはならないか,又は,PinvokeImpl 

= 1でなければならない。[ERROR] 

28) Signatureは,次の管理下呼出し規約のうちの正確に一つをもたなければならない。[ERROR] 

a) DEFAULT (0x0) 

238 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

b) VARARG (0x5) 

c) GENERIC (0x10) 

29) Signatureは,呼出し規約,DEFAULT (0x0) 又はGENERIC (0x10)をもたなければならない。[CLS] 

30) メソッドがStaticでないときは,また,そのときに限り,Signatureの呼出し規約バイトは,ビット

HASTHIS (0x20)が1となる。[ERROR] 

31) メソッドがStaticならば,Signatureの呼出し規約バイトは,ビットHASTHIS (0x20) が0でなけれ

ばならない。[ERROR] 

32) 識別情報のEXPLICITTHIS (0x40) が設定されているならば,HASTHIS (0x20)もまた,設定されてい

なければならない(EXPLICITTHISが設定されているならば,コードは正当性検証できないことに注

意せよ。)。[ERROR] 

33) ビットEXPLICITTHIS (0x40) は,識別情報において関数ポインタのためだけに設定可能とする。す

なわち,そのMethodDefSigがFNPTR (0x1B)によって先行される識別情報だけとする。[ERROR] 

34) RVA = 0ならば,次のいずれかとする。[ERROR] 

− Flags.Abstract = 1 

− ImplFlags.Runtime = 1 

− Flags.PinvokeImpl = 1 

35) RVA != 0ならば,次のすべてとする。[ERROR] 

a) Flags.Abstractは0でなければならない。 

b) ImplFlags.CodeTypeMaskは,Native,CIL又はRuntimeのうちの正確に一つの値を取らなければ

ならない。 

c) RVAは,このファイルにおけるCILコードストリームの中を指さなければならない。 

36) Flags.PinvokeImpl = 1ならば,[ERROR] 

− RVA = 0及びメソッドが表ImplMapの行要素を所有する。 

37) Flags.RTSpecialName = 1ならば,Nameは次のいずれかでなければならない。[ERROR] 

a) .ctor(オブジェクト構築子メソッド) 

b) .cctor(クラス構築子メソッド) 

38) 逆に,Nameが上の特別名のいずれかならば,Flags.RTSpecialNameは,1でなければならない。[ERROR] 

39) Name = .ctor(オブジェクト構築子メソッド)ならば,次となる。 

a) Signatureの戻り型は,ELEMENT̲TYPE̲VOIDでなければならない(23.1.16参照)。[ERROR] 

b) Flags.Staticは0でなければならない。[ERROR] 

c) Flags.Abstractは0でなければならない。[ERROR] 

d) Flags.Virtualは0でなければならない。[ERROR] 

e) 型ʻOwnerʼは,表TypeDefにおける妥当なクラス又は値型(<Module>又はインタフェースであっ

てはならない。)。[ERROR] 

f) 

与えられたʻownerʼには,0個以上の.ctorsがあり得る。 

40) Name = .cctor(クラス構築子メソッド)ならば,次となる。 

a) Signatureの戻り型は,ELEMENT̲TYPE̲VOIDでなければならない(23.1.16参照)。[ERROR] 

b) Signatureは,呼出し規約としてDEFAULT (0x0)をもたなければならない。[ERROR] 

c) Signatureには,仮引数が与えられてはならない。[ERROR] 

d) Flags.Staticは1でなければならない。[ERROR] 

239 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

e) Flags.Virtualは0でなければならない。[ERROR] 

f) Flags.Abstractは0でなければならない。[ERROR] 

41) 表TypeDefにおける任意の与えられた行要素によって所有されるメソッド集合にも,.cctorという

名前のメソッドが0個又は1個存在できる(決して2個以上はない。)。[ERROR] 

注記 参考情報終わり 

22.27 MethodImpl : 0x19 

MethodImplは,CLIによって提供される省略時の継承規則をコンパイラによって上書きさせる。元々の

利用は,インタフェースI及びJからメソッド“Foo”を継承したクラス“C”に対して,(そのvtableにお

いて“Foo”のためのただ一つのスロットをもつよりも)両方のメソッドの実装を提供することを可能に

するものであった。しかし,MethodImplは,他の理由のためにも利用でき,それは,次に述べる妥当性確

認規則で定義された制約の範囲内でのコンパイラ作成者の能力によってだけ限られる。 

上の例では,Classは,“C”を,MethodDeclarationは,I::Fooを,MethodBodyは,I::Fooの実装(“C”

内のメソッド本体又は“C”の上位クラスによって実装されるメソッド本体)を提供するメソッドを指定

する。 

表MethodImplには,次の欄がある。 

− Class(表TypeDefへの添字) 

− MethodBody(表MethodDef又はMemberRefへの添字。より正確にはMethodDefOrRef符号化添字) 

− MethodDeclaration(表MethodDef又はMemberRefへの添字。より正確にはMethodDefOrRef符号化添

字。) 

ILAsmは,表MethodImplの行要素を指定するために指令.overrideを使う(10.3.2及び15.4.1参照)。 

注記 ここから参考情報であり規定ではない。 

1) 表MethodImplには,ゼロ個以上の行要素がある。 

2) Classは,表TypeDefにおける妥当な行要素を指さなければならない。[ERROR] 

3) MethodBodyは,表MethodDef or MethodRefにおける妥当な行要素を指さなければならない。[ERROR] 

4) MethodDeclarationによって指されるメソッドは,Flags.Virtualを1にしていなければならない。

[ERROR] 

5) MethodDeclarationによって指されるメソッドの所有者型では,Flags.Sealed = 0であってはならない。

[ERROR] 

6) MethodDeclarationによって指されるメソッドは,Class又はClassの上位クラスのメンバでなければな

らない(MethodImplは,コンパイラが任意のメソッド本体にフックを仕込むことを許さない。)。

[ERROR] 

7) MethodBodyによって指されるメソッドは,仮想でなければならない。[ERROR] 

8) MethodBodyによって指されるメソッドは,Method.RVA != 0でなければならない(例えば,PInvokeか

ら到達可能な管理外メソッドであってはならない。)。[ERROR] 

9) MethodDeclarationは,Classの先祖連鎖(Extends連鎖によって到達される。)又はClassのインタフェ

ース木(InterfaceImpl要素を介して到達される。)にあるメソッドを指さなければならない。[ERROR] 

10) MethodDeclarationによって指されるメソッドは,最終であってはならない(そのFlags.Finalは,0で

なければならない。)。[ERROR] 

11) MethodDeclarationによって指されるメソッドは,Classへアクセス可能でなければならない。[ERROR] 

12) MethodBodyで定義されるメソッド呼出し情報は,MethodDeclarationで定義されるメソッド呼出し情報

240 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

と対応しなければならない。[ERROR] 

13) Class+MethodDeclarationに関して重複した行要素があってはならない。[ERROR] 

注記 参考情報終わり 

22.28 MethodSemantics : 0x18 

表MethodSemanticsには,次の欄がある。 

− Semantics(型MethodSemanticsAttributes用の2バイトビットマスク,23.1.12参照) 

− Method(表MethodDefへの添字) 

− Association(表Event 又は Propertyへの添字。より正確にはHasSemantics符号化添字) 

表MethodSemanticsの行要素は,指令.property(箇条17参照)及び.event(箇条18参照)によっ

て埋められる。さらなる情報は,22.13を参照する。 

注記 ここから参考情報であり規定ではない。 

1) 表MethodSemanticsには,ゼロ個以上の行要素がある。 

2) Semanticsは,指定された値しかとってはならない。[ERROR] 

3) Methodは,表MethodDefの妥当な行要素を指さなければならず,その行要素は,この行要素が記述す

る特性又はイベントと同じクラスで定義されるメソッドのためのものでなければならない。[ERROR] 

4) 与えられた特性又はイベントのすべてのメソッドは,同じアクセス可能性(すなわち,その行要素の

Flagsの下位フィールドMemberAccessMask。)をもち,CompilerControlledであってはならない。

[CLS] 

5) Semanticsは,次の制約を受ける。 

− この行要素が特性のためならば,Setter,Getter又はOtherのうちのちょうど一つが1でなけ

ればならない。[ERROR] 

− この行要素がイベントのためならば,AddOn,RemoveOn,Fire又はOtherのうちのちょうど一

つが1でなければならない。[ERROR] 

6) この行要素がイベントのためであり,そのSemanticsがAddon又はRemoveOnならば,Methodによ

って指される表MethodDef の行要素は,委譲を仮引数としてとり,値を返さない。[ERROR] 

7) この行要素がイベントのためであり,そのSemanticsがFireならば,表MethodDefにおいてMethod

で指される行要素は,どのような型の値でも返せる。 

8) 特性のそれぞれについては,setter若しくはgetter,又は,それら両方がなければならない。[CLS] 

9) Nameがxxxである特性のためのgetterメソッドは,get̲xxxと呼ばれなければならない。[CLS] 

10) Nameがxxxである特性のためのsetterメソッドは,set̲xxxと呼ばれなければならない。[CLS] 

11) 特性にgetterメソッド及びsetterメソッドの両方があるならば,この両方のメソッドは,下位フ

ィールドFlags.MemberAccessMaskの値が同じでなければならない。[CLS] 

12) 特性にgetterメソッド及びsetterメソッドの両方があるならば,この両方のメソッドは,

Method.Flags.Virtualの値が同じでなければならない。[CLS] 

13) getterメソッド及びsetterメソッドは,いずれも,Method.Flags.SpecialName = 1でなければなら

ない。[CLS] 

14) どのgetterメソッドも,フィールドProperty.Typeで指される呼出し情報に対応する返却値の型をと

らなければならない。[CLS] 

15) setterメソッドの最後の仮引数は,いずれも,フィールドProperty.Typeで指される呼出し情報に対

応する型でなければならない。[CLS] 

241 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

16) どのsetterメソッドも,Method.Signatureにおける返却値の型ELEMENT̲TYPE̲VOID(23.1.16参照)

をとらなければならない。[CLS] 

17) 特性に添字があるならば,getterメソッド及びsetterメソッドの添字は,個数と型とが一致しな

ければならない。[CLS] 

18) Nameがxxxのイベントに対するAddOnメソッドは,いずれも呼出し情報void add̲xxx

(<DelegateType> handler)をとらなければならない。[CLS] 

19) Nameがxxxのイベントに対するRemoveOnメソッドは,いずれも呼出し情報void remove̲xxx

(<DelegateType> handler)をとらなければならない。[CLS] 

20) Nameがxxxのイベントに対するFireメソッドは,いずれも呼出し情報void raise̲xxx(Event e)

をとらなければならない。[CLS] 

注記 参考情報終わり 

22.29 MethodSpec : 0x2B 

表MethodSpecには,次の欄がある。 

− Method [表 MethodDef 又は MemberRef への添字であり,この行がどの総称メソッドを参照するか

を指定する。すなわち,この行がどの総称メソッドのインスタンスかを指定する。具体的には,

MethodDefOrRef (24.2.6)コード化添字とする。] 

− Instantiation [このインスタンス化の識別情報を保持するヒープ Blob (23.2.15)への添字。] 

表MethodSpecは,インスタンス化された総称メソッドの識別情報を記録する。 

総称メソッドのインスタンス化(すなわちMethod及びInstantiationの組合せ)は,表の単一行によって

表現されなければならない。 

注記 ここから参考情報であり規定ではない。 

1) 表MethodSpec は,ゼロ個以上の行をもってよい。 

2) 1個以上の行が表 MethodDef 又は MemberRef を参照できる。(同じ総称メソッドのインスタンス化

が複数あってもよい。) 

3) Instantiation に蓄えられた識別情報は, Methodに蓄えられた総称メソッドの識別情報の正当なインス

タンス化でなければならない。  [ERROR] 

4) Method+Instantiation に基づいた重複行があってはならない。 [ERROR] 

注記 参考情報終わり 

22.30 Module : 0x00 

表Moduleには,次の欄がある。 

− Generation(2バイト値,予約済み,ゼロでなければならない。) 

− Name(ヒープStringへの添字。) 

− Mvid(ヒープGUIDへの添字。同じモジュールの二つの版を区別するのに用いるだけのGUID。) 

− EncId(ヒープGUIDへの添字,予約済み,ゼロでなければならない。) 

− EncBaseId(ヒープGUIDへの添字,予約済み,ゼロでなければならない。) 

欄Mvidは,モジュールのこのインスタンスを識別する,ヒープGUIDにおける一意なGUID(24.2.5参

照)を指さなければならない。Mvidは,CLI規格適合処理系による読込みでは無視できる。Mvidは,JIS X 

5718(附属書A)において規定されたアルゴリズム,又は,他の互換性のあるアルゴリズムを用いて,モ

ジュールごとに新たに生成されることが望ましい。 

注記1 GUIDは,Globally Unique IDentifierの略であり,十六進符号を用いて表示される16バイト長

242 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

の数である。GUIDは,RPC及びCORBAでのUUID(Universally Unique IDentifiers)及びCOM

におけるCLSID,GUID,IIDに使われるよく知られたアルゴリズムによって生成できる。 

注記2 根拠としては,VESそのものは,Mvidを使わないが,他のツール(この規格の範囲外である

デバッガなど)は,Mvidがほとんど常にモジュールごとに異なるという事実に依存している

からとする。 

欄Generation,EncId 及び EncBaseIdは,ゼロとして書かれ,規格適合処理系からは無視される。表Module

の行要素は,アセンブリの指令.moduleから得られる。 

注記 ここから参考情報であり規定ではない。 

1) 表Moduleには,ただ一つだけの行要素がなければならない。[ERROR] 

2) Nameは,ヒープStringにある非空文字列を指さなければならない。この文字列は,このモジュールと

解決される,任意の対応文字列 ModuleRef.Name に正確に対応するのが望ましい。[ERROR] 

3) Mvidは,ヒープGUIDの非nullのGUIDを指さなければならない。[ERROR] 

注記 参考情報終わり 

22.31 ModuleRef : 0x1A 

表ModuleRefには,次の欄がある。 

− Name(ヒープStringへの添字。) 

表ModuleRefの行要素は,アセンブリの指令.module externから得られる。(6.5参照) 

注記 ここから参考情報であり規定ではない。 

1) Nameは,ヒープStringにある非空文字列を指さなければならない。この文字列によって,CLIが,対

象モジュールを探し出せなければならない(通常は,モジュールを保持するのに使われるファイルの

名前である。)。[ERROR] 

2) 行要素が重複するのは望ましくない。[WARNING] 

3) Nameは,表Fileの欄Nameにおける要素と一致するのが望ましい。さらに,その要素によって,CLI

が,対象モジュールを探し出せなければならない(通常は,モジュールを保持するのに使われるファ

イルの名前である。)。[ERROR] 

注記 参考情報終わり 

22.32 NestedClass : 0x29 

表NestedClassには,次の欄がある。 

− NestedClass(表TypeDefへの添字。) 

− EnclosingClass(表TypeDefへの添字。) 

NestedClassは,字句的に,その取り囲む型のプログラムʻ内部ʼで定義される。 

注記 ここから参考情報であり規定ではない。 

表NestedClassは,どの型定義が,他のどの型定義内で入れ子になっているかを記録する。ILAsmを含め

て,通常の高水準言語では,入れ子クラスは,字句的に,その取り囲む型のプログラムʻ内部ʼで定義さ

れる。 

1) 表NestedClassには,ゼロ個以上の行要素がある。 

2) NestedClassは,表TypeDefの妥当な行要素を指さなければならない。[ERROR] 

3) EnclosingClassは,表TypeDefの妥当な行要素を指さなければならない(特に,表TypeRefを指すこと

が許されていないことに注意する。)。[ERROR] 

4) 重複した行要素があること(すなわち,NestedClass及びEnclosingClassに関して同じ値があること。)

243 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

は望ましくない。[WARNING] 

5) 与えられた型は,一つの取り囲むものによってだけ入れ子になることができる。したがって,

EnclosingClassに関して異なる値をもちながらNestedClassに関して同じ値をもつ二つの行要素はあり

えない。[ERROR] 

6) 与えられた型は,幾つかの異なる入れ子型をʻ所有ʼできるから,EnclosingClassに対して同じ値をもち,

NestedClassに対して異なる値をもつ二つ以上の行要素をもつことは全く正当とする。 

注記 参考情報終わり 

22.33 Param : 0x08 

表Paramには,次の欄がある。 

− Flags(型ParamAttributes用の2バイトビットマスク,23.1.13参照) 

− Sequence(2バイト定数。) 

− Name(ヒープStringへの添字。) 

概念的には,表Paramのすべての行要素は,表MethodDefにおける唯一の行要素に所有される。 

表Paramの行要素は,メソッド宣言(15.4参照)のパラメータ,又は,メソッドに付加された属性.param

(15.4.1参照)から得られる。 

注記 ここから参考情報であり規定ではない。 

1) 表Paramには,ゼロ個以上の行要素がある。 

2) どの行要素も,表MethodDefにおける唯一の行要素に所有される。[ERROR] 

3) Flagsは,指定された値(すべての正当な組合せ。)だけをとる。[ERROR] 

4) Sequenceは,0以上,かつ,所有者メソッドでの仮引数の個数以下でなければならない。Sequenceの

値が0のものは,所有者メソッドの返却値の型を参照する。したがって,仮引数は,1から番号付け

られる。[ERROR] 

5) 同じメソッドによって所有される表Paramの引き続く行要素は,Sequence値の昇順で並べなければな

らない。ただし,空隙があってもよい。[WARNING] 

6) Flags.HasDefault = 1ならば,この行要素は表Constantにおいて正確に一つの行要素をもたなければな

らない。[ERROR] 

7) Flags.HasDefault = 0ならば,表Constantにおいては,この行要素によって,どの行要素も所有されて

はならない。[ERROR] 

8) 仮引数は,省略時の値を与えることはできないから,Flags.HasDefaultは,0でなければならない。[CLS] 

9) Flags.FieldMarshal = 1ならば,この行要素は表FieldMarshalにおいて正確に一つの行要素を所有しな

ければならない。[ERROR] 

10) Nameは,null又は非nullとなる。 

11) Nameは,ヒープStringにある非空文字列を指さなければならない。[WARNING] 

注記 参考情報終わり 

22.34 Property : 0x17 

メタデータ内の特性は,クラス上で定義されたメソッドの集まりをまとめる手段であり,名前を与える

だけであり,それ以上ではない。それらのメソッドは,通常,既にクラス上で定義された,メソッドget̲ 及

びset̲ であり,他のメソッドと同様に表MethodDef に挿入される。これらの関連は,下図のように三つ

の個別の表に保持される。 

background image

244 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

表PropertyMapの第3行要素は,左の表TypeDefの第2行要素(MyClass),及び右の表Propertyの第4

行要素,Fooと呼ばれる特性の行要素を指す。この構成は,MyClassがFooと呼ばれる特性をもつことを

示す。しかし,特性Fooにʻ属すʼ表MethodDefのメソッドはどのように集めればよいか。この関連は,表

MethodSemanticsに含まれる。その行要素2は,右の特性Fooと,左の表MethodDefの第2行要素(get̲Foo

と呼ばれるメソッド。)を指す。さらに,表MethodSemanticsの第3行要素は,右の特性Fooと,左の表

MethodDefの行要素3(set̲Fooと呼ばれるメソッド。)を指す。色づけが示すように,MyClassには,Bar

と呼ばれる他の特性もあって,get̲Bar及びset̲Barの二つのメソッドをもつ。 

表Propertyは,他の表からの既存の行要素を一緒にまとめる以外はほとんどしない。表Propertyには,

Flags,Name(例 この例のFoo及びBar。)及びTypeという欄がある。さらに,表MethodSemanticsには,

指しているメソッドがset̲,get̲ 又はotherかを記録する欄がある。 

注記 CLS(第1章参照)では,インスタンス,仮想及び静的特性を参照する。(欄Typeからの)特

性の識別情報は,インスタンス及び仮想特性が識別情報においてビット“HASTHIS”を1にし

ており(23.2.1参照),静的特性はそうでないことによって,静的特性を区別するために用いる

ことができる。インスタンス特性と仮想特性との区別は,メソッドgetter及びsetterの識

別情報に依存する。CLSでは,これらのメソッドは,ともに仮想か,ともにインスタンスかの

いずれかになる。 

表Property ( 0x17 )には,次の欄がある。 

− Flags(型PropertyAttributes用の2バイトビットマスク,23.1.14参照) 

− Name(ヒープStringへの添字。) 

− Type[ヒープBlobへの添字(この欄の名前は,誤解を招きやすい。これは,表TypeDef 又は TypeRef 

を指すわけではなく,特性のヒープBlobにある識別情報を指す。)。] 

注記 ここから参考情報であり規定ではない。 

1) 表Propertyには,ゼロ個以上の行要素がある。 

2) 各行要素は,表PropertyMapにおける唯一の所有者行要素を(上に示したように)もたなければなら

ない。[ERROR] 

3) PropFlagsは,指定された値(すべての組合せが妥当。)だけをとることができる。[ERROR] 

4) Nameは,ヒープStringにある非空文字列を指さなければならない。[ERROR] 

5) 文字列Nameは,妥当なCLS識別子でなければならない。[CLS] 

6) Typeは,ヒープBlobにおいて非null識別情報を指さなければならない。[ERROR] 

245 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

7) Typeによって指される識別情報は,特性のための妥当な識別情報でなければならない(すなわち,先

頭バイトの下半分は0x8である。)。この先頭バイトを除けば,識別情報は,特性のget̲メソッドと同

じ識別情報となる。[ERROR] 

8) 表TypeDefの与えられた行要素によって所有される行要素においては,Name+Typeに関して重複があ

ってはならない。[ERROR] 

9) Nameに関して重複する行要素があってはならない。ここで,欄Name はCLS衝突識別子規則を用い

て比較する(特に,特性は,そのTypeによってオーバロードできない。クラスには二つの特性があっ

てはならない。例えば,"int Foo" 及び "String Foo"。)。[CLS] 

注記 参考情報終わり 

22.35 PropertyMap : 0x15 

表PropertyMapには,次の欄がある。 

− Parent(表TypeDefへの添字。) 

− PropertyList(表Propertyへの添字。)これは,Parent.によって所有される特性の連続的な実行の先頭を

印付ける。この実行は,次の小さいほうへと継続する。 

− 表Propertyの最終行要素。 

− この表PropertyMapの次の行要素のPropertyListを検査することによって見つかった特性の次の実行。 

表PropertyMap及びPropertyは,クラス上に指令.propertyを置くことによって得られる(箇条17参

照)。 

注記 ここから参考情報であり規定ではない。 

1) 表PropertyMapには,ゼロ個以上の行要素がある。 

2) Parentに関して重複した行要素があってはならない(与えられたクラスは,その属性並びの先頭に一

つだけʻポインタʼをもつことができる。)。[ERROR] 

3) PropertyListに関して重複した行要素があってはならない(異なるクラスは,表Propertyにおいて行要

素を共有できない。)。[ERROR] 

注記 参考情報終わり 

22.36 StandAloneSig : 0x11 

識別情報は,メタデータのヒープBlobに蓄えられる。ほとんどの場合,それらは,Field.Signature,

Method.Signature,MemberRef.Signatureなどといった表の欄から指される。しかし,どのメタデータ表から

も指されない識別情報のためのメタデータ字句を必要とする場合が二つある。表StandAloneSigは,この必

要のためにある。欄は一つだけであり,ヒープBlobの識別情報を指す。 

この識別情報は,次のいずれかを記述しなければならない。 

− メソッド コード生成器は,CIL命令calliのそれぞれに対応して,表StandAloneSigに行要素を生成す

る。その行要素は,命令calliの関数ポインタ被演算子のcall-site識別情報を指す。 

− 局所変数 コード生成器は,各メソッドに対して,その局所変数すべてを記述するため,表

StandAloneSigに行要素を生成する。ILAsmにおける指令.localsが表StandAloneSigの行要素を生成

する。 

表StandAloneSigには,次の欄がある。 

− Signature(ヒープBlobへの添字。) 

例 

// On encountering the calli instruction, ilasm generates a signature 

246 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

// in the blob heap (DEFAULT, ParamCount = 1, RetType = int32, Param1 

= int32), 

// indexed by the StandAloneSig table: 

.assembly Test {} 

.method static int32 AddTen(int32) 

{ ldarg.0 

  ldc.i4  10 

  add 

  ret 

.class Test 

{ .method static void main() 

  { .entrypoint 

    ldc.i4.1 

    ldftn int32 AddTen(int32) 

    calli int32(int32) 

    pop 

    ret 

  } 

注記 ここから参考情報であり規定ではない。 

1) 表StandAloneSigには,ゼロ個以上の行要素がある。 

2) Signatureは,ヒープBlobの妥当な識別情報識別情報を指さなければならない。[ERROR] 

3) Signatureによって指される識別情報識別情報'blob'は,妥当なMETHOD 又はLOCALS識別情報でなけ

ればならない。[ERROR] 

4) 重複した行要素が許される。 

注記 参考情報終わり 

22.37 TypeDef : 0x02 

表TypeDefには,次の欄がある。 

− Flags(型TypeAttributes用の4バイトビットマスク,23.1.15参照) 

− TypeName(ヒープStringへの添字。) 

− TypeNamespace(ヒープStringへの添字。) 

− Extends(表TypeDef,TypeRef 又は TypeSpecへの添字。より正確にはTypeDefOrRef符号化添字(24.2.6

参照)。) 

− FieldList(表Fieldへの添字。この型が所有する連続した一連のフィールドの先頭を印付ける。)この

一連の続きは,次のうちの小さい方までとする。 

247 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

− 表Fieldの最終行要素。 

− この表TypeDefの次の行要素のFieldListを検査することによって見つかった,次のフィールド。 

− MethodList(表MethodDefへの添字。この型が所有する連続した一連のメソッドの先頭を印付ける。)

この一連の続きは,次のうちの小さい方までとする。 

− 表MethodDefの最終行要素。 

− この表TypeDefの次の行要素のMethodListを検査することによって見つかった,次のメソッド 

どの型も次のいずれか一つでなければならないことに注意する。 

− クラス(Flags.Interface = 0,かつ,最終的にSystem.Objectから導出される。) 

− インタフェース(Flags.Interface = 1。) 

− 値型,最終的にSystem.ValueTypeから導出される。 

与えられた型のいずれについても,他の型へのポインタの,二つの別々の異なったʻ継承ʼ連鎖がある

(ポインタは,実際には,メタデータ表への添字として実装される。)。この二つの連鎖は次とする。 

− 拡張連鎖 表TypeDefの欄Extendsで定義される。通常は,導出されたクラスが基底クラスを拡張する

(常に,一つだけの基底クラス。)。 

− インタフェース連鎖 表InterfaceImplで定義される。通常は,クラスがゼロ個,1個又は複数のイン

タフェースを実装する。 

この二つの連鎖(拡張及びインタフェース。)は,常に,メタデータにおいて別々に保持される。拡張連

鎖は,1対1関係,すなわち,一つのクラスが正確に一つの他のクラス(直接基底クラスと呼ばれる。)を

拡張する(又は,ʻ導出されるʼ。)。インタフェース連鎖は,1対多関係を表現できる。すなわち,一つの

クラスが二つ以上のインタフェースを実装できる。 

インタフェースは,一つ以上の他のインタフェースからもʻ継承ʼできる。メタデータは,これらのリ

ンクを表InterfaceImplによって蓄える(この用語の名称は,不適切である。“実装”は関与しない。より適

切な名称は,表Interface又は表InterfaceInheritであろう。)。 

もう一つの特殊な型は,ILAsmにおいて宣言された,取り囲む型宣言の中で字句的に入れ子になった,

入れ子型である。型が入れ子になっているかどうかは,その下位フィールドFlags.Visibilityの値によって

決定できる。値が{NestedPublic,NestedPrivate,NestedFamily,NestedAssembly,NestedFamANDAssem,

NestedFamORAssem}のうちのいずれかでなければならない。 

型が総称ならば,その仮引数は,表GenericParam(22.20)で定義される。表GenericParam の要素は,

表TypeDefの要素を参照する。表TypeDefから表GenericParamへの参照はない。 

注記 ここから参考情報であり規定ではない。 

継承階層の根は次の図のように表される。 

background image

248 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

システム定義の根は,System.Object一つだけである。すべてのクラス及び値型は,最終的に,

System.Objectから導出されなければならない。クラスは,他のクラスから(循環をもたない単一連鎖

によって)任意の必要な深さまで導出できる。この拡張継承連鎖は,上の図では,太い矢印で表される。 

クラスSystem.Delegateの詳細については,次を参照する。 

インタフェースは,相互には継承しないが,実装されるゼロ個以上のインタフェースを規定する。イン

タフェース要求連鎖は,上手では,細い破線矢印で表される。これは,インタフェースとクラス及び値型

とのリンクを含む。このクラス及び値型は,インタフェースを実装するという。 

普通の値型(すなわち,列挙を除いたもの,後述を参照する。)は,System.ValueTypeから直接継承

すると定義される。通常の値型は,二つ以上の深さに導出されることはできない(言い換えれば,利用者

定義値型は,封印されていなければならない。)。利用者定義Enumは,System.Enumから直接導出され

なければならない。Enumは,System.Enumから二つ以上の深さに導出されることはできない(言い換え

れば,利用者定義Enumは,封印されていなければならない。)。System.Enumは,System.ValueType

から直接導出する。 

利用者定義委譲は,System.Delegateから直接導出する。委譲は,二つ以上の深さに導出することが

できない。 

型宣言の指令については,箇条9を参照する。 

1) 表TypeDefには,1個以上の行要素がある。 

2) Flags 

a) Flagsは,指定された値だけをとることができる。[ERROR] 

b) Flagsは,SequentialLayout及びExplicitLayoutを0又は1に設定できる(いずれも設定さ

れていない省略時は,AutoLayoutとする。)。[ERROR] 

c) Flagsは,UnicodeClass及びAutoClassを0又は1に設定できる(いずれも設定されていない

と,省略時は,AnsiClassとする。)。[ERROR] 

d) Flags.HasSecurity = 1ならば,次の条件のうちの少なくとも一つが真でなければならない。[ERROR] 

− この型は,表DeclSecurityにおいて少なくとも一つの行要素を所有する。 

− この型は,SuppressUnmanagedCodeSecurityAttributeと呼ばれるカスタム属性をもつ。 

e) この型が表DeclSecurityにおいて一つ以上の行要素を所有するならば,Flags.HasSecurityは,1でな

ければならない。[ERROR] 

f) 

この型が,SuppressUnmanagedCodeSecurityAttributeと呼ばれるカスタム属性をもつなら

249 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

ば,Flags.HasSecurityは,1でなければならない。[ERROR] 

g) インタフェースにおいて,HasSecurityが1に設定されていることは,正当であることに注意す

る。しかし,セキュリティシステムは,そのインタフェースに付与されているすべての許可要求を

無視する。 

3) Nameは,ヒープStringにある非空文字列を指さなければならない。[ERROR] 

4) 文字列Nameは,妥当なCLS識別子でなければならない。[CLS] 

5) Namespaceは,null又は非nullとなる。 

6) Namespaceが非nullならば,それは,ヒープStringにある非空文字列を指さなければならない。[ERROR] 

7) Namespaceが非nullならば,その文字列は,妥当なCLS識別子でなければならない。[CLS] 

8) (System.Objectを唯一の例外として)すべてのクラスは,ただ一つの他のクラスを拡張しなけれ

ばならない。したがって,クラスのExtendsは,非null でなければならない。[ERROR] 

9) System.ObjectのExtends値はnullでなければならない。[ERROR] 

10) System.ValueTypeのExtends値はSystem.Objectでなければならない。[ERROR] 

11) System.Objectを唯一の例外として,どのクラスにおいても,Extendsは,表TypeDef又はTypeRef

の妥当な行要素を指さなければならない。ここで,妥当とは,1 <= 行要素 <= 行要素数を意味する。

さらに,行要素そのものも,(インタフェース又は値型ではなくて)クラスでなければならない。さら

に,基盤クラスが封印されていてはならない(そのFlags.Sealedは0でなければならない。)。[ERROR] 

12) クラスは,自分自身又は自分の子(すなわち導出されたクラス。)をどれも拡張できない。さもないと,

階層木にループができてしまう。[ERROR](総称型については,9.1及び9.2を参照する。) 

13) インタフェースは,決して他の型を拡張しない。したがって,Extendsはnullでなければならない[イ

ンタフェースは,確かに,他のインタフェースを実装するが,この関係は,欄Extendsによってでは

なく,表InterfaceImplによって捕そく(捉)されることを思い出せ。]。[ERROR] 

14) FieldListは,null又は非nullとなる。 

15) クラス又はインタフェースは,ゼロ個以上のフィールドをʻ所有ʼできる。 

16) 値型は,少なくとも一つのフィールドを定義するか又は,非ゼロClassSizeを提供することによって,

非ゼロのサイズをもたなければならない。[ERROR] 

17) FieldListが非nullならば,それは,表Fieldの妥当な行要素を指さなければならない。ここで,妥当

とは,1 <= 行要素 <= 行要素数を意味する。[ERROR] 

18) MethodListは,null又は非nullとなる。 

19) 型は,ゼロ個以上のメソッドをʻ所有ʼできる。 

20) 値型の実行時サイズは,1Mバイト(0x100000バイト)を超えてはならない。[ERROR] 

21) MethodListが非nullならば,それは,表MethodDefの妥当な行要素を指さなければならない。ここで,

妥当とは,1 <= 行要素 <= 行要素数を意味する。[ERROR] 

22) 一つ以上の抽象メソッドをもつクラスは,インスタンス化できず,Flags.Abstract = 1でなければなら

ない。クラスによって所有されるメソッドとは,その基底クラス及びそれが実装するインタフェース

から継承するすべてのメソッド,及びそのMethodListによって定義されるものがすべて含まれること

に注意する(CLIは,クラス定義を実行時に解析しなければならない。一つ以上の抽象メソッドをも

つが,Flags.Abstract = 0となっているクラスを見つければ,例外を送出する。)。[ERROR] 

23) インタフェースは,Flags.Abstract = 1でなければならない。[ERROR] 

24) 抽象型が構築子メソッド(すなわち名前.ctorのメソッド。)をもつことは正当とする。 

250 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

25) 非抽象型(すなわち,Flags.Abstract = 0)は,契約が必要とするすべてのメソッドについて実装(本

体)を提供しなければならない。そのメソッドは,基底クラス,実装するインタフェース,又は,そ

れ自身の定義から継承できる。実装は,基底クラス又はそれ自身の定義から継承できる。[ERROR] 

26) インタフェース(Flags.Interface = 1)は,静的フィールド(Field.Static = 1)を所有できるが,インス

タンスフィールド(Field.Static = 0)を所有できない。[ERROR] 

27) インタフェースは,封印できない(Flags.Interface = 1ならば,Flags.Sealedは0でなければならない。)。

[ERROR] 

28) インタフェース(Flags.Interface = 1)によって所有されるすべてのメソッドは,抽象(Flags.Abstract = 

1)でなければならない。[ERROR] 

29) 表TypeDefにおいては(入れ子型でない限り,次を参照する。),Namespace+Nameに関して重複した

行要素があってはならない。[ERROR] 

30) 入れ子型ならば,表TypeDefにおいては,Namespace+Name+Owner行要素InNestedClassTableに関し

て重複した行要素があってはならない。[ERROR] 

31) フィールドNamespace+NameをCLS衝突識別子規則を用いて比較したときに,(入れ子型でない限り,

次を参照する。)重複した行要素があってはならない。[CLS] 

32) 入れ子型ならば,Namespace+Name+Owner行要素InNestedClassTableに関して,フィールド

Namespace+NameをCLS衝突識別子規則を用いて比較したときに,重複した行要素があってはならな

い。[CLS] 

33) Extends = System.Enumならば(すなわち,型が利用者定義Enumであるなら),次となる。 

a) 封印されていなければならない(Sealed = 1)。[ERROR] 

b) それ自身のメソッドをもってはならない(MethodList連鎖は長さがゼロでなければならない。)。

[ERROR] 

c) インタフェースを実装してはならない(この型の表InterfaceImplに要素があってはならない。)。

[ERROR] 

d) 特性をもってはならない。[ERROR] 

e) イベントをもってはならない。[ERROR] 

f) 

静的フィールドは,リテラルでなければならない(Flags.Literal = 1となる。)。[ERROR] 

g) 一つ以上の静的リテラルフィールドをもたなければならず,それらはすべて同じ列挙型でなければ

ならない。[CLS] 

h) 正確に一つの組込整数型のインスタンスフィールドをもたなければならない。[CLS] 

i) 

インスタンスフィールドの文字列Nameは,"value̲̲"でなければならない。それは,RTSpecialName

で印付けられていなければならない。その型は,CLS整数型のいずれかでなければならない。[CLS] 

j) 

リテラル以外の静的フィールドをもってはならない。)。[ERROR] 

34) (上で定義された)入れ子型は,表NestedClassにおいて正確に一つの行要素を所有しなければならな

い。ここで,ʻ所有ʼとは,その欄NestedClassがこの型定義のために字句TypeDefをもつ,その表

NestedClassの行要素を意味する。[ERROR] 

35) 値型は,封印されていなければならない。[ERROR] 

注記 参考情報終わり 

22.38 TypeRef : 0x01 

表TypeRefには,次の欄がある。 

251 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

− ResolutionScope[表Module,ModuleRef,AssemblyRef 又は TypeRefへの添字又はnull。より正確には

ResolutionScope符号化添字(24.2.6参照)。] 

− TypeName(ヒープStringへの添字。) 

− TypeNamespace(ヒープStringへの添字。) 

注記 ここから参考情報であり規定ではない。 

1) ResolutionScopeは,正確に次のいずれかでなければならない。 

a) null このとき,この型の表ExportedTypeには一つの行要素がなければならない。その欄は,どこ

で型が定義されたかを示す字句File又は字句AssemblyRefを含まなければならない。[ERROR] 

b) 字句TypeRef 入れ子型である場合(入れ子型かどうかは,例えば,その表TypeDefの欄Flagsを調

べれば分かる。)。アクセス可能性下位フィールドでは,tdNestedXXXのいずれかが1でなければ

ならない。[ERROR] 

c) 字句ModuleRef 目標型が,これと同じアセンブリの中で他のモジュールで定義されている場合。

[ERROR] 

d) 字句Module 目標型が同じモジュールで定義されている場合。これは,モジュールCLI(“圧縮メ

タデータ”)で起こることは望ましくない。[WARNING] 

e) 字句AssemblyRef 目標型が現在のモジュールとは異なるアセンブリで定義されている場合。

[ERROR] 

2) TypeNameは,ヒープStringにある非空文字列を指さなければならない。[ERROR] 

3) TypeNamespaceは,null又は非nullとなる。 

4) TypeNamespaceが非nullならば,それは,ヒープStringにある非空文字列を指さなければならない。

[ERROR] 

5) 文字列TypeNameは,妥当なCLS識別子でなければならない。[CLS] 

6) 重複した行要素があってはならない。ここで,重複した行要素は,同じResolutionScope,TypeName

及びTypeNamespaceをもつ。[ERROR] 

7) 重複した行要素があってはならない。ここで,フィールドTypeName 及びTypeNamespaceは,CLS衝

突識別子規則を用いて比較される。[CLS] 

注記 参考情報終わり 

22.39 TypeSpec : 0x1B 

表TypeSpecは,ヒープBlobに蓄えられる型の仕様を指すただ一つだけの欄をもつ。これは,(ただ単に

ヒープBlobへの添字というだけでなく。)その型のメタデータ字句を与える。これは,通常,配列クラス

の生成や配列クラスの呼出しメソッドなどの配列操作に必要となる。 

表TypeSpecには,次の欄がある。 

− Signature(ヒープBlobへの添字。ここで,Blobは,23.2.14に規定されたように書式指定される。) 

字句TypeSpecは,字句TypeDef又はTypeRefをとる,特に次のCLI命令で使うことができることに注意

する。 

castclass,cpobj,initobj,isinst,ldelema,ldobj,mkrefany,newarr,refanyval,sizeof,stobj,box,unbox。 

注記 ここから参考情報であり規定ではない。 

1) 表TypeSpecには,ゼロ個以上の行要素がある。 

2) Signatureは,ヒープBlobの妥当な型仕様を指さなければならない。[ERROR] 

3) Signatureに関して重複した行要素があってはならない。[ERROR] 

background image

252 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

注記 参考情報終わり 

23 メタデータ論理形式における他の構造体 

23.1 ビットマスク及びフラグ 

23.1は,メタデータ表の中で使用されるフラグ及びビットマスクについて示す。 

規格適合処理系が,この規格で規定されていない(例えばフラグのような)メタデータ構造体に出会っ

たときに,その実装の振る舞いは未規定とする。 

23.1.1 AssemblyHashAlgorithmの値 

アルゴリズム 

値 

None 

0x0000 

予約済み (MD5) 

0x8003 

SHA1  

0x8004 

23.1.2 AssemblyFlagsの値 

フラグ 

値 

記述 

PublicKey 

0x0001 

アセンブリ参照は,完全な(ハッシュされていない。)
公開かぎ(鍵)を保持する。 

SideBySideCompatible  

0x0000 

アセンブリは,並行互換である。 

予約済み 

0x0030 

予約済み。両方のビットはゼロでなければならない。 

Retargetable 

0x0100 

実行時に使用されるこのアセンブリの実装が,コンパ
イル時で参照された版と一致しなくてもよい(この表
に続くテキストを参照する。)。 

EnableJITcompileTracking  

0x8000 

予約済み(CLIの規格適合処理系は,読込み時に,こ
の設定値を無視できる。実装は,CILからプラットフ
ォーム固有のコードに変換するコンパイラがCILから
プラットフォーム固有のコードへの対応付けを生成す
るのが望ましいことを示すためにこのビットを用いて
もよい。)。 

DisableJITcompileOptimizer 

0x4000 

予約済み(CLIの規格適合処理系は,読込み時に,こ
の設定値を無視できる。実装は,CILからプラットフ
ォーム固有のコードに変換するコンパイラが最適化さ
れたコードを生成しないのが望ましいことを示すため
にこのビットを用いてもよい。)。 

可搬性のあるプログラムでは,Retargetable(0x100)ビットは,この規格の中で規定されたアセンブリ

へのすべての参照上で設定されなければならない。 

23.1.3 文化圏のための値 

ar-SA 

ar-IQ 

ar-EG 

ar-LY 

ar-DZ 

ar-MA 

ar-TN 

ar-OM 

ar-YE 

ar-SY 

ar-JO 

ar-LB 

ar-KW 

ar-AE 

ar-BH 

ar-QA 

bg-BG 

ca-ES 

zh-TW 

zh-CN 

zh-HK 

zh-SG 

zh-MO 

cs-CZ 

da-DK 

de-DE 

de-CH 

de-AT 

de-LU 

de-LI 

el-GR 

en-US 

en-GB 

en-AU 

en-CA 

en-NZ 

en-IE 

en-ZA 

en-JM 

en-CB 

en-BZ 

en-TT 

en-ZW 

en-PH 

es-ES-Ts 

es-MX 

es-ES-Is 

es-GT 

background image

253 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

es-CR 

es-PA 

es-DO 

es-VE 

es-CO 

es-PE 

es-AR 

es-EC 

es-CL 

es-UY 

es-PY 

es-BO 

es-SV 

es-HN 

es-NI 

es-PR 

fi-FI 

fr-FR 

fr-BE 

fr-CA 

fr-CH 

fr-LU 

fr-MC 

he-IL 

hu-HU 

is-IS 

it-IT 

it-CH 

ja-JP 

ko-KR 

nl-NL 

nl-BE 

nb-NO 

nn-NO 

pl-PL 

pt-BR 

pt-PT 

ro-RO 

ru-RU 

hr-HR 

lt-sr-SP 

cy-sr-SP 

sk-SK 

sq-AL 

sv-SE 

sv-FI 

th-TH 

tr-TR 

ur-PK 

id-ID 

uk-UA 

be-BY 

sl-SI 

et-EE 

lv-LV 

lt-LT 

fa-IR 

vi-VN 

hy-AM 

lt-az-AZ 

cy-az-AZ 

eu-ES 

mk-MK 

af-ZA 

ka-GE 

fo-FO 

hi-IN 

ms-MY 

ms-BN 

kk-KZ 

ky-KZ 

sw-KE 

lt-uz-UZ 

cy-uz-UZ 

tt-TA 

pa-IN 

gu-IN 

ta-IN 

te-IN 

kn-IN 

mr-IN 

sa-IN 

mn-MN 

gl-ES 

kok-IN 

syr-SY 

div-MV 

RFC1766のロケール名称に注意する。典型的な文字列は“en-US”である。最初の部分(例における“en”。)

は,ISO 639の文字列(ラテンアルファベット文字の小文字を使用する。ダイアクリティカルマークが付

いた文字のダイアクリティカルマークは使用されない。)第2の部分(例における“US”。)は,ISO 3166

の文字列(ISO 639に似ているが,大文字を使用する。)を使用する。言い換えれば,それぞれはよく知ら

れているASCII文字のa-z及びA-Zとする。しかしながら,RFC 1766は最初の部分が小文字,第2の部分

が大文字であることを推奨する一方,大文字及び小文字の混在を許している。したがって,妥当性検証規

則は,文化圏が上記リスト中の文字列の一つであることを検査するが,その検査では大文字と小文字との

違いを無視する。大文字と小文字との違いを無視するとは,よく知られているようにU+0080より小さい

値を畳み込むことである。 

23.1.4 イベントのためのフラグ [EventAttributes] 

フラグ 

値 

記述 

SpecialName 

0x0200 

イベントは特殊である。 

RTSpecialName  

0x0400 

CLIはイベントの名前に依存した“特殊”な振る舞いを提供する。 

23.1.5 フィールドのためのフラグ[FieldAttributes] 

フラグ 

値 

記述 

FieldAccessMask 

0x0007 

この3ビットは次の七つの値の一つを含む。 

CompilerControlled 

0x0000 

参照できないメンバ。 

Private 

0x0001 

親型によってだけアクセス可能。 

FamANDAssem 

0x0002 

このアセンブリ中だけの下位型によってアクセス可能。 

Assembly 

0x0003 

アセンブリ中のすべてからアクセス可能。 

Family 

0x0004 

型及び下位型によってだけアクセス可能。 

FamORAssem 

0x0005 

下位型によっていかなる場所及びアセンブリ中のすべてからアク
セス可能。 

background image

254 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

Public 

0x0006 

この有効範囲フィールド契約属性に対する可視性をもっているす
べてからアクセス可能。 

Static 

0x0010 

型又はインスタンスごとに定義される。 

InitOnly 

0x0020 

フィールドは初期化後に書き込まずに,単に初期化できる。 

Literal 

0x0040 

値はコンパイル時定数である。 

NotSerialized 

0x0080 

(型がリモート処理される場合,このフィールドを直列化しない
のが望ましいことを示すために)予約済み。 

SpecialName 

0x0200 

フィールドは特殊である。 

オペレーション間属性 

PInvokeImpl 

0x2000 

実装はPInvokeを通じて転送される。 

追加のフラグ 

RTSpecialName 

0x0400 

CLIは,フィールドの名前に依存した“特殊な”振る舞いを提供す
る。 

HasFieldMarshal 

0x1000 

フィールドは組換え情報をもつ。 

HasDefault 

0x8000 

フィールドは省略時の値をもつ。 

HasFieldRVA 

0x0100 

フィールドはRVAをもつ。 

23.1.6 ファイルのためのフラグ[FileAttributes] 

フラグ 

値 

記述 

ContainsMetaData 

0x0000 

資源ファイルではない。 

ContainsNoMetaData 

0x0001 

資源ファイル又は他の非メタデータを含んでいるファイルであ
る。 

23.1.7 総称仮引数のためのフラグ[GenericParamAttributes] 

フラグ 

値 

記述 

VarianceMask 

0x0003 

この2ビットは,次の三つの値の一つを含む。 

None 

0x0000 

総称仮引数は変性及び特殊制約をもたない。 

Covariant 

0x0001 

総称仮引数は共変である。 

Contravariant 

0x0002 

総称仮引数は反変である。 

SpecialConstraintMask 

0x001C 

この3ビットは,次の三つの値の一つを含む。 

ReferenceTypeConstraint 

0x0004 

総称仮引数はclass特殊制約をもつ。 

otNullableValueTypeConstraint 0x0008 

総称仮引数はvaluetype特殊制約をもつ。 

DefaultConstructorConstraint 

0x0010 

総称仮引数は.ctor特殊制約をもつ。 

23.1.8 ImplMapのためのフラグ[PInvokeAttributes] 

フラグ 

値 

記述 

NoMangle 

0x0001 

PInvokeは指定されたメンバ名を使用する。 

文字集合 

CharSetMask 

0x0006 

資源ファイル又は他の非メタデータを含んでいるファイルであ
る。この2ビットは次の四つの値の一つを含む。 

CharSetNotSpec 

0x0000 

CharSetAnsi 

0x0002 

CharSetUnicode 

0x0004 

CharSetAuto 

0x0006 

SupportsLastError 

0x0040 

目的関数に関する情報。フィールドには適切でない。 

呼出し規約 

CallConvMask 

0x0700 

この3ビットは次の五つの値の一つを含む。 

CallConvWinapi 

0x0100 

CallConvCdecl 

0x0200 

CallConvStdcall 

0x0300 

CallConvThiscall 

0x0400 

background image

255 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

CallConvFastcall 

0x0500 

23.1.9 ManifestResourceのためのフラグ[ManifestResourceAttributes] 

フラグ 

値 

記述 

VisibilityMask 

0x0007 

この3ビットは次の二つの値の一つを含む。 

Public 

0x0001 

資源は,アセンブリから移出される。 

Private 

0x0002 

資源は,アセンブリに非公開である。 

23.1.10 メソッドのためのフラグ [MethodAttributes] 

フラグ 

値 

記述 

MemberAccessMask 

0x0007 

この3ビットは次の七つの値の一つを含む。 

CompilerControlled 

0x0000 

参照できないメンバ。 

Private 

0x0001 

親型によってだけアクセス可能。 

FamANDAssem 

0x0002 

このアセンブリ中の下位型によってだけアクセス可能。 

Assem 

0x0003 

アセンブリ中のすべてからアクセス可能。 

Family 

0x0004 

型及びサブ型によってだけアクセス可能。 

FamORAssem 

0x0005 

下位型のいかなる場所及びアセンブリ中のすべてからアクセス可
能。 

Public 

0x0006 

この有効範囲に対する可視性をもっているすべてからアクセス可
能。 

Static 

0x0010 

型又はインスタンスごとに定義される。 

Final 

0x0020 

メソッドは上書きできない。 

Virtual 

0x0040 

メソッドは仮想である。 

HideBySig 

0x0080 

メソッドは,名前及び識別情報又は名前だけによって,隠ぺいする。 

VtableLayoutMask 

0x0100 

vtable属性を取り出すために,このマスクを使用する。このビット
は次の二つの値の一つを含む。 

ReuseSlot 

0x0000 

メソッドはvtable中の既存のスロットを再使用する。 

NewSlot 

0x0100 

メソッドは常にvtable中の新しいスロットを得る。 

Strict 

0x0200 

メソッドがアクセス可能ならば,上書きだけできる。 

Abstract 

0x0400 

メソッドは実装を提供しない。 

SpecialName 

0x0800 

メソッドは特殊である。 

相互運用属性 

PInvokeImpl 

0x2000 

実装はPInvokeを通じて転送される。 

UnmanagedExport 

0x0008 

予約済み。規格適合処理系では,ゼロにしなければならない。 

追加フラグ 

RTSpecialName 

0x1000 

CLIはメソッドの名前で依存した“特殊”な振る舞いを提供する。 

HasSecurity 

0x4000 

メソッドは,それに関連するセキュリティをもつ。 

RequireSecObject 

0x8000 

メソッドは,セキュリティコードを含んでいる別のメソッドを呼び
出す。 

23.1.11 メソッドのためのフラグ[MethodImplAttributes] 

フラグ 

値 

記述 

CodeTypeMask 

0x0003 

この2ビットは次の四つの値の一つを含む。 

IL 

0x0000 

メソッド実装はCILである。 

Native 

0x0001 

メソッド実装はプラットフォーム固有である。 

OPTIL 

0x0002 

予約済み。規格適合処理系では,ゼロにしなければならない。 

Runtime 

0x0003 

メソッド実装は処理系によって提供される。 

ManagedMask 

0x0004 

コードが管理下又は管理外かを指定するフラグ。このビットは次
の二つの値の一つを含む。 

Unmanaged 

0x0004 

メソッド実装は管理外であるか,そうでなければ管理下にある。 

Managed 

0x0000 

メソッド実装は管理下にある。 

background image

256 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

実装情報及び相互オペレーション 

ForwardRef 

0x0010 

メソッドが定義済みであることを示す。主として差込みシナリオ
の中で使用される。 

PreserveSig 

0x0080 

予約済み。規格適合処理系は,無視できる。 

InternalCall 

0x1000 

予約済み。規格適合処理系では,ゼロにしなければならない。 

Synchronized 

0x0020 

メソッドは,本体全体で単一スレッドである。 

NoInlining 

0x0008 

メソッドをインライン展開できない。 

MaxMethodImplVAl 

0xffff 

範囲検査値。 

23.1.12 MethodSemanticsのためのフラグ [MethodSemanticsAttributes] 

フラグ 

値 

記述 

Setter 

0x0001 

特性のための設定子。 

Getter 

0x0002 

特性のための取得子。 

Other 

0x0004 

特性又はイベントのための他のメソッド。 

AddOn 

0x0008 

イベントのためのAddOnメソッド。 

RemoveOn 

0x0010 

イベントのためのRemoveOnメソッド。 

Fire 

0x0020 

イベントのためのメソッドを発生させる。 

23.1.13 Paramsのためのフラグ [ParamAttributes] 

フラグ 

値 

記述 

In 

0x0001 

Paramは[in]である。 

Out 

0x0002 

Paramは[out]である。 

Optional 

0x0010 

Paramは省略可能である。 

HasDefault 

0x1000 

Paramは省略時の値をもつ。 

HasFieldMarshal 

0x2000 

ParamはFieldMarshalをもつ。 

Unused 

0xcfe0 

予約済み。規格適合処理系では,ゼロでなければならない。 

23.1.14 特性のためのフラグ [PropertyAttributes] 

フラグ 

値 

記述 

SpecialName 

0x0200 

特性は特殊である。 

RTSpecialName 

0x0400 

処理系メタデータ内部APIは名前符号化を検査するのが望ましい。 

HasDefault 

0x1000 

特性は省略時の値をもっている。 

Unused 

0xe9ff 

予約済み。規格適合処理系では,ゼロでなければならない。 

23.1.15 型のためのフラグ [TypeAttributes] 

フラグ 

値 

記述 

可視属性 

VisibilityMask 

0x00000007 可視性情報を取り出すために,このマスクを使用する。この3

ビットは次の八つの値の一つを含む 

NotPublic 

0x00000000 クラスは公開の有効範囲をもたない。 

Public 

0x00000001 クラスは公開の有効範囲をもつ。 

NestedPublic 

0x00000002 クラスは公開可視性をもつ入れ子である。 

NestedPrivate 

0x00000003 クラスは非公開可視性をもつ入れ子である。 

NestedFamily 

0x00000004 クラスはファミリ可視性をもつ入れ子である。 

NestedAssembly 

0x00000005 クラスはアセンブリ可視性をもつ入れ子である。 

NestedFamANDAssem 

0x00000006 クラスはファミリ及びアセンブリ可視性をもつ入れ子である。 

NestedFamORAssem 

0x00000007 クラスはファミリ又はアセンブリ可視性をもつ入れ子である。 

クラス配置属性 

LayoutMask  

0x00000018 クラス配置情報を取り出すためにこのマスクを使用する。この

2ビットは次の三つの値の一つを含む。 

AutoLayout 

0x00000000 クラスは自動配置される。 

SequentialLayout  

0x00000008 クラスは連続して配置される。 

background image

257 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

ExplicitLayout 

0x00000010 配置は明示的に与えられる。 

クラス意味属性 

ClassSemanticsMask 

0x00000020 クラス意味情報を取り出すためにこのマスクを使用する。この

ビットは次の二つの値の一つを含む。 

Class 

0x00000000 型はクラスである。 

Interface 

0x00000020 型はインタフェースである。 

クラス意味に加えての特殊な意味 

Abstract 

0x00000080 クラスは抽象である。 

Sealed 

0x00000100 クラスは拡張できない。 

SpecialName 

0x00000400 クラス名は特殊である。 

実装属性 

Import 

0x00001000 クラス又はインタフェースが移入される。 

Serializable 

0x00002000 予約済み(クラスは直列化できる)。 

文字列形式属性 

StringFormatMask 

0x00030000 プラットフォーム固有の相互運用性のための文字列情報を取

り出すために,このマスクを使用する。この2ビットは次の四
つの値の一つを含む。 

AnsiClass 

0x00000000 LPSTRはANSIとして解釈される。 

UnicodeClass 

0x00010000 LPSTRはUnicodeとして解釈される。 

AutoClass 

0x00020000 LPSTRは自動的に解釈される。 

CustomFormatClass 

0x00030000 CustomStringFormatMaskによって指定される規格ではない符号

化である。 

CustomStringFormatCl
ass 

0x000C0000 プラットフォーム固有の相互運用性のための規格ではない符

号化情報を取り出すためにこのマスクを使用する。この2ビッ
トの値の意味は指定されない。 

クラス初期化属性 

BeforeFieldInit 

0x00100000 最初の静的フィールドアクセスの前にクラスを初期化する。 

追加フラグ 

RTSpecialName 

0x00000800 CLIは型の名前に依存した“特殊”な振る舞いを提供する。 

HasSecurity 

0x00040000 型は,それに関連するセキュリティをもつ。 

23.1.16 識別情報の中で使用される要素型 

次の表は,ELEMENT̲TYPE定数に対する値を列挙する。これらは,メタデータ識別情報blob中で広範

囲に使用される(23.2参照)。 

名前 

値 

備考 

ELEMENT̲TYPE̲END 

0x00 

並びの終了の印をつける。 

ELEMENT̲TYPE̲VOID 

0x01 

ELEMENT̲TYPE̲BOOLEAN 

0x02 

ELEMENT̲TYPE̲CHAR 

0x03 

ELEMENT̲TYPE̲I1 

0x04 

ELEMENT̲TYPE̲U1 

0x05 

ELEMENT̲TYPE̲I2 

0x06 

ELEMENT̲TYPE̲U2 

0x07 

ELEMENT̲TYPE̲I4 

0x08 

ELEMENT̲TYPE̲U4 

0x09 

ELEMENT̲TYPE̲I8 

0x0A 

ELEMENT̲TYPE̲U8 

0x0b 

ELEMENT̲TYPE̲R4 

0x0c 

ELEMENT̲TYPE̲R8 

0x0d 

background image

258 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

ELEMENT̲TYPE̲STRING 

0x0e 

ELEMENT̲TYPE̲PTR 

0x0f 

Typeが続く。 

ELEMENT̲TYPE̲BYREF 

0x10 

Typeが続く。 

ELEMENT̲TYPE̲VALUETYPE 

0x11 

TypeDef又はTypeRef字句が続く。 

ELEMENT̲TYPE̲CLASS 

0x12 

TypeDef又はTypeRef字句が続く。 

ELEMENT̲TYPE̲VAR 

0x13 

総称型定義の総称仮引数で,numberとして表現する。 

ELEMENT̲TYPE̲ARRAY 

0x14 

type rank boundsCount bound1 … loCount lo1 … 

ELEMENT̲TYPE̲GENERICINST 0x15 

総称型のインスタンス化。type type-arg-count  type-1 ... type-n
が続く。 

ELEMENT̲TYPE̲TYPEDBYREF 

0x16 

ELEMENT̲TYPE̲I 

0x18 

System.IntPtr 

ELEMENT̲TYPE̲U 

0x19 

System.UIntPtr 

ELEMENT̲TYPE̲FNPTR 

0x1b 

完全なメソッドの識別情報が続く。 

ELEMENT̲TYPE̲OBJECT 

0x1c 

System.Object 

ELEMENT̲TYPE̲SZARRAY 

0x1d 

0を下限とする単一配列。 

ELEMENT̲TYPE̲MVAR 

0x1e 

<数>として表現された,総称メソッド定義における総称仮引
数。 

ELEMENT̲TYPE̲CMOD̲REQD 

0x1f 

必す(須)修飾子: TypeDef又はTypeRef字句が続く。 

ELEMENT̲TYPE̲CMOD̲OPT 

0x20 

省略可能修飾子: TypeDef又はTypeRef字句が続く。 

ELEMENT̲TYPE̲INTERNAL 

0x21 

CLIの内に実装される。 

ELEMENT̲TYPE̲MODIFIER 

0x40 

後に続く要素型の論理和として設定される。 

ELEMENT̲TYPE̲SENTINEL 

0x41 

varargメソッドの識別情報の標識。 

ELEMENT̲TYPE̲PINNED 

0x45 

アドレス固定されたオブジェクトを指す局所変数を表す。 

0x50 

型System.Typeの仮引数を表す。 

0x51 

ボックス化されたオブジェクト(23.3)を指定するためにカス
タム属性の中で使われる。 

0x52 

予約済み。 

0x53 

FIELD(23.3)を表すためにカスタム属性の中で使われる。 

0x54 

PROPERTY(22.10,23.3)を表すカスタム属性の中で使われる。 

0x55 

enum(23.3)を指定するためにカスタム属性の中で使われる。 

23.2 BLOB及び識別情報 

識別情報という用語は,関数又はメソッド用の型情報(すなわち,その仮引数の各々の型。)及びその返

却値の型について記述するために慣習的に使用される。メタデータ内では,識別情報もフィールド,特性

及び局所変数用の型情報について記述するために使用される。識別情報はそれぞれBLOBヒープにバイト

配列(として数えられた。)として格納される。次のような数種類の識別情報がある。 

− MethodRefSig(VARARG呼出しである場合に限りMethodDefSigと異なる。) 

− MethodDefSig 

− FieldSig 

− PropertySig 

− LocalVarSig 

− TypeSpec 

− MethodSpec 

識別情報'blob'の先頭のバイトの値は,それがどんな種類の識別情報かを示す。その最下位の4ビットは,

メソッド識別情報を限定するC,DEFAULT,FASTCALL,STDCALL,THISCALL又はVARARG(これらの

値は23.2.3で規定されている。),フィールド識別情報を限定するFIELD(これらの値は23.2.4で規定され

background image

259 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

ている。)又はPROPERTYの一つをもつ。23.2.1〜23.2.16では,各種類の識別情報のバイナリの'blob'書式

を定義する。定義の多くに伴う構文図式では,網掛けはそうでなければ多重図式になるものを単一の図式

に組み合わせるために使用する,伴うテキストは,網掛けの使用について記述する。 

識別情報に埋め込まれていた整数を圧縮することで,識別情報をBlobヒープ(下に記述する。)に格納

する前に圧縮する。符号化できる最大の整数は29ビットのlongの0x1FFFFFFFとする。使用される圧縮

アルゴリズムは,次のとおりとする(ビット0は最下位ビットである。) 

− 値が0 (0x00)以上127 (0x7F)以下である場合,1バイトの整数(ビット7はクリアし,値はビット0か

ら6の中に保持される。)として符号化する。 

− 値が27(0x80)以上214‒ 1 (0x3FFF) 以下である場合,ビット15を設定し,ビット14をクリアした2バ

イトの整数(値はビット0から13の中に保持される。)として符号化する。 

− そうでなければ,ビット31を設定,ビット30を設定及びビット29をクリアした4バイトの整数(値

はビット0から28の中に保持される。)として符号化する。 

− null文字列は予約済みの単一バイト0xFFで表現し,それに続くデータをもたないことが望ましい。 

注記 次の表は幾つかの例を示す。1番目の欄は,よく知られている(Cのような)16進数記法で表

現された値である。2番目の欄は,PEファイルの中に表れるように,その値をファイル内で連

続しているより高いバイトオフセットに位置した結果の連続したバイトで,圧縮した結果を示

す(これは,通常の2進整数をPEファイルの中に配置する方法とは反対の順序である。)。 

元の値 

圧縮された表現 

0x03 

03 

0x7F 

7F(7個のビットを1に設定) 

0x80 

8080 

0x2E57 

AE57 

0x3FFF 

BFFF 

0x4000 

C000 4000 

0x1FFF FFFF 

DFFF FFFF 

“圧縮した”フィールドの最上位ビット(PEファイルの中で遭遇する最初のビット。)は,その値と同

様に,1,2又は4バイトを占有しているかを明らかにすることができる。これについては,上で説明した

ように,“圧縮した”値は,上位バイト先行(big-endian)の順序,すなわちファイル中の一番小さなオフ

セットに最上位バイトがくるように格納される。 

識別情報は,ELEMENT̲TYPE̲xxx(23.1.16参照)のような定数値を多数利用する。特に,識別情報は,

次の二つの修飾子を含む。 

ELEMENT̲TYPE̲BYREF この要素は,管理下ポインタ(第1章参照)とする。この修飾子は,LocalVarSig

(23.2.6),Param(23.2.10)又はRetType(23.2.11)の定義の中にだけにもつことができる。それは,フィ

ールド(23.2.4)の定義内で出現してはならない。 

ELEMENT̲TYPE̲PTR この要素は,管理下ポインタ(第1章参照)とする。この修飾子は,LocalVarSig 

(23.2.6),Param(23.2.10),RetType(23.2.11)又はフィールド(23.2.4)の定義中に出現できる。 

23.2.1 MethodDefSig 

MethodDefSigはMethod.Signature欄によって添字指定される。それは,メソッド又は大域関数の識別情

報を取り込む。MethodDefSigの構文図式は次のとおりとする。 

background image

260 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

この図は次の省略形を使用する。 

HASTHIS = 0x20,呼出し規約中のinstanceキーワードを符号化するために使用する

(15.3参照)。 

EXPLICITTHIS = 0x40,呼出し規約中のexplicitキーワードを符号化するために使

用する(15.3参照)。 

DEFAULT = 0x0,呼出し規約中のdefaultキーワードを符号化するために使用する(15.3

参照)。 

VARARG = 0x5,呼出し規約中のvarargキーワードを符号化するために使用する(15.3

参照)。 

GENERIC = 0x10,一つ以上の総称仮引数をもつメソッドを示すために使用する。 

識別情報の最初のバイトは,HASTHIS,EXPLICITTHIS及び呼出し規約のビット(DEFAULT,VARARG

又はGENERIC)を保持する。これらは一緒にʼ論理和として設定される。 

GenParamCount は,メソッドの総称仮引数の個数とする。これは,圧縮されたint32である。 

注記 総称メソッドに対しては,MethodDef及びMemberRefはGenParamCountと一緒にGENERIC呼

出し規約を含まなければならない。これらは,CLIが総称メソッドをそれが含んでいる総称仮

引数の個数によって多重定義できるようにする結合にとって重要である。 

ParamCountは,仮引数の個数を保持する(0以上の)整数とする。それは0から0x1FFFFFFFの間のあ

らゆる数値でありうる。コンパイラは,'blob'に格納する前に(ParamCountは,メソッド仮引数をカウント

するが,メソッドの返却値の型は含まない。),同じくそれを圧縮する(第2章,メタデータ妥当性検証参

照)。 

RetType項目は,メソッドの返却値(23.2.11参照)の型について記述する。 

Param項目は,メソッドの各々の仮引数の型について記述する。Param項目(23.2.10参照)のParamCount

インスタンスがなければならない。 

23.2.2 MethodRefSig 

MethodRefSigは,MemberRef.Signature欄によって添字指定される。これはメソッドに呼出し元識

background image

261 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

別情報を供給する。通常は,この呼出し元識別情報は,対象のメソッドの定義の中で指定された識別情報

と厳密に一致しなければならない。例えば,メソッドFooが二つのunsigned int32sを取って,及び

voidを返却すると定義されている場合,すべての呼出し元は,厳密に二つのunsigned int32sを取っ

て,及びvoidを返却する識別情報を添字指定しなければならない。この場合,MethodRefSigのための構文

図式はMethodDefSig用のそれと同一とする(23.2.1参照)。 

呼出し元における識別情報は,VARARG呼出し規約を備えたメソッドに対してだけ,その定義時のもの

とは異なる。この場合,呼出し識別情報は,追加のVARARG実引数(例えば,C構文の中での“...”に対

応する)に関する情報を取り込むために拡張される。この場合の構文図式は次のとおりとする。 

この図式は次の省略形を使用する。 

HASTHIS = 0x20,呼出し規約中のinstanceキーワードを符号化するために使用する

(15.3参照)。 

EXPLICITTHIS = 0x40,呼出し規約中のexplicitキーワードを符号化するために使

用する(15.3参照)。 

VARARG = 0x5,呼出し規約中のvarargキーワードを符号化するために使用する(15.3

参照)。 

SENTINEL = 0x41(23.1.16参照),仮引数並び中の “...”を符号化するために使用する

(15.3参照)。 

− 識別情報の最初のバイトは,HASTHIS,EXPLICITTHIS及びVARARG呼出し規約のビットを保持す

る。これらは一緒に論理和として設定される。 

− ParamCountは,仮引数の個数を保持する(0以上の)整数とする。それは0〜0x1FFFFFFFの間の任意

の数値をとることができる,コンパイラは,'blob'へ格納する前に(また,ParamCountは,メソッド仮

引数を数えるが,メソッドの返却値の型は含まない。),同じくそれを圧縮する。 

− RetType項目は,メソッドの返却値の型について記述する(23.2.11参照)。 

− Param項目は,メソッドの各々の仮引数の型について記述する。Param項目のParamCountインスタン

スがなければならない(23.2.10参照)。 

Param項目は,メソッドの各々の仮引数の型について記述する。これらは,Param項目のParamCount

インスタンスでなければならない。これは,VARARGメソッドのためのMethodDefSigと同じように開始す

る(23.2.1参照)。しかし,SENTINEL字句は,追加のVARARG実引数について記述するために追加のParam

項目の後に続けて付け加えられる。ParamCount項目はSENTINELバイト(0x41)の前後の識別情報のParam

項目の総数を示さなければならないことに注意する。 

呼出し元が追加の実引数を供給しない例外的なケースでは,識別情報はSENTINELを含んではならない

background image

262 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

(これは,SENTINELを通らずにMethodRefSig定義の最後へ行く下の矢印が示す経路である。)。 

23.2.3 StandAloneMethodSig 

StandAloneMethodSigはStandAloneSig.Signature欄によって添字指定される。StandAloneMethodSig

は,通常はcalli命令の実行の準備として作成される。それは呼出し元識別情報を表すという点で,

MethodRefSigに似ているが,その呼出し規約は管理外対象を指定してもよい(calli命令は管理下又は管理

外のコードのいずれかを呼び出す。)。その構文図式は次のとおりとする。 

この図式では次の省略形を使用する(15.3参照)。 

HASTHISを0x20で表す。 

EXPLICITTHISを0x40で表す。 

DEFAULTを0x0で表す。 

VARARGを0x5で表す。 

Cを0x1で表す。 

STDCALLを0x2で表す。 

THISCALLを0x3で表す。 

FASTCALLを0x4で表す。 

SENTINELを0x41で表す(23.1.16及び15.3参照)。 

− 識別情報の最初のバイトは,HASTHIS,EXPLICITTHIS及びDEFAULT,VARARG,C,STDCALL,

THISCALL,又はFASTCALLのいずれかの呼出し規約のビットをもつ。これらは論理和を取って同時

に設定される。 

− ParamCountは,非vararg 及びvararg仮引数の合計の個数を保持する整数とする。それは0から

0x1FFFFFFFの間の任意の数値をとることができる,コンパイラは,'blob'へ格納する前に,同じくそ

れを圧縮する(第2章,メタデータ妥当性検証参照)。(また,ParamCountは,メソッド仮引数を数え

るが,メソッドの返却値の型は含まない。)。 

− RetType項目は,メソッドの返却値の型について記述する(23.2.11参照)。 

− 最初のParam項目は,メソッドの各々の非vararg仮引数の型について記述する。(省略可能な)2番目

background image

263 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

のParam項目は,メソッドの各々のvararg仮引数の型について記述する。Param項目のParamCount

インスタンスがなければならない(23.2.10参照)。 

これは様々なメソッドの識別情報の中で最も複雑である。別々の二つの図式を一つの図式にまとめて,

網掛けによって区別する。このように,呼出し規約DEFAULT(管理下),STDCALL,THISCALL及び

SENTINEL(管理外)に対し,その識別情報はSENTINEL項目の直前で終了する(これらはすべて非vararg

識別情報とする。)。しかしながら,管理下及び管理外のvararg呼出し規約に対しては,VARARG(管理下)

識別情報及びC(管理外)識別情報は,SENTINEL及び最後のParam項目(必ずしも必要ではない。)を取

り込むことができる。これらの省略可能なものは,構文図式中の箱の網掛けによって示される。 

23.2.4 FieldSig 

FieldSigは,Field.Signature欄又は(メソッドではなくフィールドへの参照を指定する場合は)

MemberRef.Signature欄によって添字指定される。識別情報はフィールドの定義を取り込む。フィールドは

クラスの静的若しくはインスタンスのフィールド又は大域変数でもよい。FieldSigの構文図式を次に示す。 

この図式は次の省略形を使用する。 

FIELDを0x6の代わりに用いる。 

CustomModは,23.2.7で定義される。Typeは,23.2.12で規定される。 

23.2.5 PropertySig 

PropertySigはProperty.Type欄によって添字指定される。それは,特性(本質的には取得子メソッドの識

別情報。)のための次の型情報を含む。 

− その取得子メソッドに供給される仮引数の個数。 

− 特性の基底型(その取得子メソッドによって返却された型。)。 

− 取得子メソッドの各仮引数の型情報(すなわち,添字仮引数。)。 

取得子及び設定子の識別情報は次のように正確に関連づけられることに注意する。 

− 取得子のparamCount仮引数の型は,設定子の最初のparamCount仮引数と厳密に同じとする。 

− 取得子の返却値の型は,設定子に供給された最後の仮引数の型と厳密に同じとする。 

PropertySigのための構文図式を次に示す。 

識別情報の最初のバイトは,HASTHIS及びPROPERTYのビットを保持する。これらは論理和を取って

同時に設定される。 

Typeは,この特性の取得子メソッドによって返却される型を指定する。Typeは,23.2.12で定義される。

Paramは,23.2.10で定義される。 

ParamCountは,取得子メソッドの中に添字仮引数の個数を保持する(0以上の)整数とする(23.2.1参

照)。ParamCountは,メソッド仮引数を数えるだけで,特性のメソッドの基底型は含まない。 

23.2.6 LocalVarSig 

background image

264 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

LocalVarSigはStandAloneSig.Signature欄によって添字指定される。それは,メソッドのすべての局所変

数の型を含む。その構文図式は次のとおりである。 

この図式は次の省略形を使用する。 

0x7をLOCAL̲SIGで表す。.locals指令に使用される(15.4.1.3参照)。 

BYREF をELEMENT̲TYPE̲BYREFで表す(23.1.16参照)。 

Constraintは,23.2.9で定義される。 

Typeは,23.2.12で定義される。 

Countは局所変数の個数を保持する符号なし整数とする。それは1から0xFFFEの間の任

意の数値をとりえる。 

LocalVarSigにTypeのCountインスタンスがなければならない。 

23.2.7 CustomMod 

識別情報の中のCustomMod項目(カスタム修飾子)は,次のような構文図式をもつ。 

この図式は次の省略形を使用する。 

CMOD̲OPTをELEMENT̲TYPE̲CMOD̲OPTで表す(23.1.16参照)。 

CMOD̲REQDをELEMENT̲TYPE̲CMOD̲REQDで表す(23.1.16参照)。 

CMOD̲OPT又はCMOD̲REQD値は圧縮されている(23.2参照)。 

TypeDef表又はTypeRef表の中の行要素を添字指定するメタデータ字句はCMOD̲OPT又

はCMOD̲REQDに続く。しかし,これらの字句は,符号化及び圧縮されている(23.2.8参

照)。 

CustomModifierがCMOD̲OPTとタグ付けされる場合,移入するコンパイラは完全にそれを無視できる。

反対に,CustomModifierがCMOD̲REQDとタグ付けされる場合,すべての移入するコンパイラは周囲の識

別情報を参照するためにCustomModifierが示す意味を理解しなければならない。 

23.2.8 TypeDefOrRefEncoded 

これらの項目は,識別情報にTypeDef,TypeRef又はTypeSpec字句をぎっしり詰めて格納する方法とする

(23.2.12参照)。 

0x01000012のような通常のTypeRef字句を考慮する。0x01の先頭のバイトは,これがTypeRef字句であ

background image

265 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

ることを示す(支持されたメタデータ字句型の並びは第6章を参照する。)。下位の3バイト(0x000012)

は,TypeRef表の中の行要素番号0x12を添字指定する。 

このTypeRef字句の符号化された版は,次のように構築される。 

1) この字句が最下位の2ビットとして添字指定する表を符号化する。使用するビット値は,対象の表

がそれぞれTypeDef,TypeRef又はTypeSpec表であることを指定する0,1及び2とする。 

2) 3バイトの行要素の添字(この例では0x000012。)を2ビット左にシフトして,手順1からの2ビッ

トの符号化と論理和をとる。 

3) 結果の値を圧縮する(23.2参照)。この例は次の符号化された値になる。 

a)  encoded = TypeRef 表のための値 = 0x01 (上記1) 

b)  encoded = ( 0x000012 << 2 ) |  0x01 

              = 0x48 | 0x01 

              = 0x49 

c)  encoded = 圧縮(0x49) 

              = 0x49 

このように,識別情報'blob'の中で0x01000012という4バイトの領域を必要とする元の正規なTypeRef

字句値の代わりに,このTypeRef字句は単一バイトとして符号化される。 

23.2.9 Constraint 

識別情報の中のConstraint項目は,いまのところ,対象の型を実行時ヒープの中でアドレス固定して,

ごみ集めの動作によって移動されないように指定するELEMENT̲TYPE̲PINNED(23.1.16)を唯一のとり

うる値としてもつ。 

制約はLocalVarSig(FieldSigではない。)の内でだけ適用できる。局所変数の型は,参照型(言い換えれ

ば,それは例えばオブジェクト又は文字列のような実際の変数を指す。)又は,BYREF項目をもつかのい

ずれかでなくてはならない。この理由は,局所変数は実行時スタック上に割り付けられ,けっして実行時

ヒープには割り付けられないので,局所変数がGCヒープ中へ割り付けられたオブジェクトを指していな

い限りは,アドレス固定は意味をなさないからである。 

23.2.10 Param 

識別情報の中のParam(仮引数)項目は次の構文図式をもつ。 

この図式は次の省略形を使用する。 

BYREFを0x10で表す(23.1.16参照)。 

TYPEDBYREFを0x16で表す(23.1.16参照)。 

CustomModは23.2.7で定義される。Typeは23.2.12で定義される。 

23.2.11 RetType 

識別情報の中のRetType(返却値の型。)項目は次の構文図式をもつ。 

background image

266 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

RetTypeは,型voidを取り込むことができるという特別な点を除いてParamと同一とする。この図式は

次の省略形を使用する。 

BYREFをELEMENT̲TYPE̲BYREFで表す(23.1.16参照)。 

TYPEDBYREFをELEMENT̲TYPE̲TYPEDBYREFで表す(23.1.16参照)。 

VOIDをELEMENT̲TYPE̲VOIDで表す(23.1.16参照)。 

23.2.12 Type 

Typeは,識別情報の中で次のように符号化される(I1はELEMENT̲TYPE̲I1の略語,U1は

ELEMENT̲TYPE̲U1などの略語である。23.1.16参照)。 

Type ::=    

BOOLEAN | CHAR | I1 | U1 | I2 | U2 | I4 | U4 | I8 | U8 | R4 | R8 | I  

| U | 

| ARRAY Type ArrayShape  (一般の配列,23.2.13参照) 

| CLASS TypeDefOrRefEncoded 

| FNPTR MethodDefSig 

| FNPTR MethodRefSig 

| GENERICINST (CLASS | VALUETYPE) TypeDefOrRefEncoded GenArgCount Type 

| MVAR number 

| OBJECT 

| PTR CustomMod* Type 

| PTR CustomMod* VOID 

| STRING 

| SZARRAY CustomMod* Type (1次元の添字が0から始まる配列すなわちベクトル) 

| VALUETYPE TypeDefOrRefEncoded 

| VAR number 

GenArgCount非終端記号は,この識別情報の中で総称実引数の個数を指定する(圧縮された)int32

値とする。 

23.2.13 ArrayShape 

ArrayShapeは次の構文図式をもつ。 

background image

267 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

Rankは,配列の次元数(1以上でなければならない。)を指定する整数(圧縮形式で格納される。23.2

参照。)とする。NumSizesは,次元数と,その大きさを示す圧縮された整数とする(0以上でなければなら

ない。)。Sizeは,次元の大きさを指定する圧縮された整数であり,この列は最初の次元から始まり,NumSizes

項目の合計に達するまで続く。同様に,NumLoBoundsは,下限(それは0以上でなければならない。)を

指定した次元の個数を示す,圧縮された整数とする。また,LoBoundは,次元の下限を指定する圧縮され

た整数であり,この列は,最初の次元から始まり,NumLoBounds項目の合計に達するまで続く。これらの

二つの列の次元のどれもスキップできないが,指定された次元の個数は,Rank未満でもよい。 

次に幾つか例を示す(要素型はすべてint32。)。 

Type 

Rank 

NumSizes 

Size 

NumLoBounds 

LoBound 

[0...2] 

I4 

[,,,,,,] 

I4 

[0...3, 0...2,,,,] 

I4 

4  3 

0  0 

[1...2, 6...8] 

I4 

2  3 

1  6 

[5, 3...5, , ] 

I4 

5  3 

0  3 

注記 型自身が配列にできるから,定義は入れ子にできる。 

23.2.14 TypeSpec 

TypeSpec字句によって添字指定されたBlobヒープ中の識別情報は,次の書式をもっている。 

TypeSpecBlob ::= 

  PTR      CustomMod*  VOID 

| PTR      CustomMod*  Type 

| FNPTR    MethodDefSig 

| FNPTR    MethodRefSig 

| ARRAY    Type  ArrayShape 

| SZARRAY  CustomMod*  Type 

| GENERICINST (CLASS | VALUETYPE) TypeDefOrRefEncoded GenArgCount Type 

Type* 

表をぎっしり詰めるために,接頭辞ELEMENT̲TYPE̲をこの一覧から省略した。したがって,例えば,

“PTR”はELEMENT̲TYPE̲PTRの省略表現である(23.1.16参照)。TypeSpecBlobが呼出し規約バイトか

ら始まらないことに注意する。したがって,それは,メタデータへ格納される様々な他の識別情報とは異

なる。 

23.2.15 MethodSpec 

MethodSpec字句によって添字指定されたBlobヒープ中の識別情報は,次の書式をもつ。 

MethodSpecBlob ::= 

  GENRICINST GenArgCount Type Type* 

GENRICINSTは,値0x0Aをもつ。 

注記 この値は,MicrosoftのCLRの実装では,IMAGE̲CEE̲CS̲CALLCONV̲GENERICINST として

知られている。 

background image

268 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

GenArgCount は,メソッドの総称実引数の個数を表す圧縮されたint32とする。blobは,インスタンス

化型を全部でGenArgCount 回繰り返して指定する。 

23.2.16 短形式識別情報 

識別情報のための一般的な規定は,ある項目を符号化する方法の中にある程度余地を残している。例え

ば,文字列を次のいずれかで符号化しても,適正であるかに見える。 

長形式: ELEMENT̲TYPE̲CLASS,TypeRef-to-System.String 

短形式:   ELEMENT̲TYPE̲STRING 

短形式だけが有効とする。次の表は,各々の長形式項目の代わりに,どの短形式を使用するのが望まし

いかを示す(今までのように,表をぎっしり詰めるために,ここではELEMENT̲TYPE̲接頭辞を省略した

から,VALUETYPEはELEMENT̲TYPE̲VALUETYPEの省略表現である。)。 

長形式 

短形式 

接頭辞 

TypeRefから変換される型 

CLASS 

System.String 

STRING 

CLASS 

System.Object 

OBJECT 

VALUETYPE 

System.Void 

VOID 

VALUETYPE 

System.Boolean 

BOOLEAN 

VALUETYPE 

System.Char 

CHAR 

VALUETYPE 

System.Byte 

U1 

VALUETYPE 

System.Sbyte 

I1 

VALUETYPE 

System.Int16 

I2 

VALUETYPE 

System.UInt16 

U2 

VALUETYPE 

System.Int32 

I4 

VALUETYPE 

System.UInt32 

U4 

VALUETYPE 

System.Int64 

I8 

VALUETYPE 

System.UInt64 

U8 

VALUETYPE 

System.IntPtr 

VALUETYPE 

System.UIntPtr 

VALUETYPE 

System.TypedReference 

TYPEDBYREF 

注記 配列はELEMENT̲TYPE̲ARRAY又はELEMENT̲TYPE̲SZARRAYのうちの一つを用いて,識別

情報の中で符号化されねばならない。System.ArrayにTypeRefを含める長形式はない。 

23.3 カスタム属性 

カスタム属性は,次の構文図式をもつ。 

すべての2進値は,下位バイト先行(little endian)書式で格納される(UTF8文字列の中で引き続くバイ

ト数を示すためだけに使われるPackedLen項目は除く。)。指定されたフィールド,仮引数又は特性がない

場合は,属性全体は空のblobとして表現される。 

CustomAttribは,値0x0001をもつ符号なしint16であるPrologから始まる。 

次に,構築子メソッドに対する固定実引数の記述がくる。それらの数値及び型は,MethodDef表のその

構築子の行要素を調べることで見いだされる。この情報はCustomAttrib自身の中では繰り返されない。構

文図式が示すように,ゼロ個以上のFixedArgが存在する(VARARG構築子メソッドは,カスタム属性の

background image

269 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

定義中では許されないことに注意する。)。 

次のことは省略可能な“名前付き”フィールド及び特性の記述とする。これは,その後に続く“名前付

き”特性又はフィールドの個数を与える符号なしint16とする,NumNamedで始まる。NumNamedは常に存

在しなければならないことに注意する。その値がゼロならば,その後に続く“名前付き”特性又はフィー

ルドはないことを示す(また,もちろん,この場合,CustomAttribはNumNamedの直後に終了しなければ

ならない。)。NumNamedが0でない場合は,NamedArgがNumNamed回繰り返される。 

各FixedArgの書式は,その実引数がSZARRAYかどうかに依存し,これは構文図式の上及び下のそれぞ

れの経路で示される。したがって,FixedArgは,単一のElemか,又はElemのNumElem回の繰返しかの

いずれかとなる。 

(SZARRAYは単一バイトの0x1dであり,ゼロを下限とする単一の配列のベクトルを表す。) 

NumElemは,SZARRAYの中の要素の個数又は値がnullであることを示す0xFFFFFFFFであることを指

定する符号なしint32とする。 

この図式では,Elemは次の形式の一つをとる。 

− 仮引数の種類が単純(bool,char,float32,float64,int8,int16,int32,int64,unsigned 

int8,unsigned int16,unsigned int32又はunsigned int64。)な場合(上の図式の一番

上の経路。),'blob'は,その2進値(Val)を含む[boolは,値0(偽)又は1(真)をもつ単一のバ

イトとし,charは2バイトのUnicode文字とする。他も同様に明白な意味をもつ。]。仮引数の種類

がenumである場合も,この形式が使用され,単にenumの基礎となる整数型の値を格納する。 

− 仮引数の種類がstringである場合(上の図式の真ん中の経路。),blobは,バイト数を示すPackedLen

の後にUTF8文字が続くSerStringを含む。その文字列がnullである場合,そのPackedLenは(それに

続く文字をもたない)値0xFFをもつ。その文字列が空(“”)である場合,そのPackedLenは(それに

続く文字をもたない)値0x00をもつ。 

− 仮引数の種類がSystem.Typeである場合(これも,上の図式の真ん中の経路。),その値は(前の段

background image

270 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

落で定義したように)その標準名を表すSerStringとして格納される。その標準名は完全型名であり,

省略可能なそれが定義されたアセンブリ,その版,文化圏及び公開かぎ(鍵)トークンが続く。アセ

ンブリ名が省略された場合,CLIは最初に現在のアセンブリを調べて,それからシステムライブラリ

(mscorlib)を調べる。これらの二つの場合は,アセンブリ名,その版,文化圏及び公開かぎ(鍵)ト

ークンを省略することが許される。 

− 仮引数の種類がSystem.Objectである場合(上の図式の下の経路。),その格納される値はその

value-typeの“ボックス化された”インスタンスを表す。この場合は,blobは実際の型のFieldOrPropType

(下を参照。)と,それに続く実引数のボックス化解除された値を含む。 

注記 この場合にnullの値を渡すことはできない。 

− 型がボックス化された単純な値型(bool,char,float32,float64,int8,int16,int32,

int64,unsigned int8,unsigned int16,unsigned int32 又は unsigned int64。)であ

る場合,1バイトの値0x51がFieldOrPropTypeの直前にくる。 

FieldOrPropTypeは,ELEMENT̲TYPE̲BOOLEAN,ELEMENT̲TYPE̲CHAR,ELEMENT̲TYPE̲I1, 

ELEMENT̲TYPE̲U1, 

ELEMENT̲TYPE̲I2,ELEMENT̲TYPE̲U2,ELEMENT̲TYPE̲I4,

ELEMENT̲TYPE̲U4,ELEMENT̲TYPE̲I8,ELEMENT̲TYPE̲U8,ELEMENT̲TYPE̲R4,

ELEMENT̲TYPE̲R8,ELEMENT̲TYPE̲STRINGのうちどれか一つでなければならない。1 次元の添

字が 0 から始まる配列は,1バイトの0x1Dと,それに続く要素型のFieldOrPropTypeと指定される

(23.1.16参照)。enumは1バイトの0x55とそれに続くSerStringとして指定される。 

NamedArgでは,(上に記述した)FixedArgの前に,それがどのフィールド又は特性を表現するか識別す

る情報がある。 

注記 CLIは同じ名前をもつフィールド及び特性を許していることを思い出せ。そこで,そのような

状況を区別する手段が必要になる。 

FIELDは,1バイトの0x53とする。 

PROPERTYは,1バイトの0x54とする。 

FieldOrPropNameは,フィールド又は特性の名前で,(上で定義したように)SerStringとして格納される。 

カスタム属性を含む多くの例は,第6章の附属書Bに載っている。 

23.4 組換え記述子 

組換え記述子は,識別情報と同様に2進値データの'blob'とする。これは,PInvokeディスパッチを介し

て管理外コードを呼び出す又は管理外コードから呼び出される場合,フィールド又は仮引数(仮引数数値

0のメソッド返却値を含む。)をどのように組み換えるのが望ましいかを示す。ILAsm構文marshalは,

擬似カスタム属性MarshalAsAttribute同様,組換え記述子の生成に使用できる(21.2.1参照)。 

CLI規格適合処理系は,既に規定された型の組換えだけを扱えればよいことに注意せよ。15.5.4を参照。 

組換え記述子は,NATIVE̲TYPE̲xxxのような形式で名付けられた定数を利用する。それらの名前及び

値を次の表に挙げる。 

background image

271 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

名前 

値 

NATIVE̲TYPE̲BOOLEAN 

0x02 

NATIVE̲TYPE̲I1 

0x03 

NATIVE̲TYPE̲U1 

0x04 

NATIVE̲TYPE̲I2 

0x05 

NATIVE̲TYPE̲U2 

0x06 

NATIVE̲TYPE̲I4 

0x07 

NATIVE̲TYPE̲U4 

0x08 

NATIVE̲TYPE̲I8 

0x09 

NATIVE̲TYPE̲U8 

0x0a 

NATIVE̲TYPE̲R4 

0x0b 

NATIVE̲TYPE̲R8 

0x0c 

NATIVE̲TYPE̲LPWSTR 

0x15 

NATIVE̲TYPE̲LPSTR  

0x14 

NATIVE̲TYPE̲INT  

0x1f 

NATIVE̲TYPE̲UINT  

0x20 

NATIVE̲TYPE̲FUNC 

0x26 

NATIVE̲TYPE̲ARRAY 

0x2a 

'blob'は,次の書式をもつ。 

MarshalSpec ::=  

  NativeIntrinsic 

| ARRAY ArrayElemType 

| ARRAY ArrayElemType ParamNum 

| ARRAY ArrayElemType ParamNum NumElem 

NativeInstrinsic ::=   

  BOOLEAN | I1 | U1 | I2 | U2 | I4 | U4 | I8 | U8 | R4 | R8 

| LPSTR | LPSTR | INT | UINT | FUNC 

ぎっしり詰めるために,NATIVE̲TYPE̲接頭辞を上記の一覧では省略した。したがって,例えば,

“ARRAY”はNATIVE̲TYPE̲ARRAYを省略形とする。 

ArrayElemType ::=  

   NativeIntrinsic  

ParamNumは,配列中の要素の個数を与えるメソッド呼出しの中の仮引数を指定する(23.2で記述され

たように圧縮された)整数とする。次の注記を参照せよ。 

NumElemは,(要素又は追加の要素の個数を指定する)23.2に記述されているように圧縮された整数と

する。次の注記を参照せよ。 

注記 例えば,次のメソッド宣言を考える。 

.method void M(int32[] arl, int32 sizel, unsigned int8[] ar2, int32 

size) { … } 

仮引数ar1は,表FieldMarshal中の行要素をもち,それは,次の書式でヒープBlob中の

MarshalSpecを添字指定するものと仮定する。 

ARRAY  MAX  2  1 

これは,この仮引数がNATIVE̲TYPE̲ARRAYに組み換えられることを示す。

(NATIVE̲TYPE̲MAXが示す)各要素の型に関する補足情報はない。ParamNumの値は2で,

background image

272 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

(“size1”と呼ばれる)メソッドの仮引数数値2が実際の配列中の要素数を指定することを示

す。ある呼出しで,その値が42と仮定する。NumElemの値は0とする。算出された配列全体

の個数の大きさ(バイト数)は,次の数式で与えられる。 

if ParamNum = 0  

   SizeInBytes = NumElem * sizeof (elem) 

else 

   SizeInBytes = ( @ParamNum +  NumElem ) * sizeof (elem) 

endif 

構文“@ParamNum”は,仮引数番号ParamNumに渡す値を表すためにここで使用されており,

この例では,42となる。各要素の大きさは,Fooの識別情報中の仮引数ar1用のメタデータか

ら算出され,すなわち大きさが4バイトのELEMENT̲TYPE̲I4(23.1.16参照)とする。 

24 メタデータの物理的な配置 

メタデータの物理的なディスク上の表現は,箇条22及び23で記述された論理的な表現を直接反映する,

すなわち,データは,メタデータ表及びヒープを表現するストリームとして格納される。複雑化の主な要

因は,論理表現が,表及び欄を添字指定するのに必要なバイト数から抽象されるのに対して,物理表現は,

論理的なメタデータのヒープ及び表をそれらの物理的な表現に対応付ける方法を明示的に定義することか

ら面倒みなければならないということである。 

特に指定しない限り,すべての2進値は下位バイト先行書式で格納される。 

24.1 固定フィールド 

すべてのCLIソフトウェア部品(メタデータ及びCIL命令)は,現在の可搬実行可能(PE)ファイル形

式(箇条25参照)の部分集合に格納される。このために,メタデータの物理表現ではフィールドのうちの

幾つかは,固定値をもつ。これらのフィールドを書き出すときには,指示された値に設定することが最善

の方法であり,読込み時には,それらを無視するのが望ましい。 

24.2 ファイルヘッダ 

24.2.1 メタデータの先頭(root) 

物理的なメタデータの先頭は,特別な識別情報から始まり,版及び他の様々な情報の数バイトに,スト

リームの個数及び存在する各ストリームに対するストリームヘッダの配列が続く。実際に符号化された表

及びヒープはストリーム中に格納され,このヘッダ配列の直後に続く。 

オフセット 

大きさ 

フィールド 

記述 

Signature 

物理メタデータの特別な識別情報。0x424A5342。 

MajorVersion 

主版,1(読込みでは無視。)。 

MinorVersion 

副版,1(読込みでは無視。)。 

予約済み 

予約済み,常に0(24.1参照)。 

12 

Length 

バイトで示した版文字列の長さm(<= 255)を4の倍数に切
り上げている。 

16 

Version 

長さm(次を参照)のUTF8符号化された版文字列。 

16+m 

次の4バイト境界xまで詰物する。 

Flags 

予約済み,常に0(24.1参照)。 

x+2 

Streams 

ストリームの個数,n。 

x+4 

StreamHeaders 

n個のStreamHdr構造体の配列。 

版文字列は,このCLI規格の任意の規格適合処理系上で実行されることが意図されているファイルでは,

background image

273 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

“Standard CLI 2005”でなければならず,かつ,このCLI規格のすべての規格適合処理系は,この版文字

列を使用したファイルを受け付けなければならない。ファイルが,CLIのベンダ固有処理系に制限される

場合には,他の文字列を使用しなければならない。この規格の将来の版は,異なる文字列を指定しなけれ

ばならないが,それも“Standard CLI”で始めなければならない。補足機能を指定する他の規格は,

“Standard□”で始まる固有の版文字列を指定しなければならない。この“□”は一つの空白を表す。実装

固有の拡張を提供するベンダは,“Standard□”で始まらない版文字列を提供しなければならない。(この規

格の最初の版では,この版文字列は“Standard CLI 2002”である。)。 

24.2.2 ストリームヘッダ 

ストリームヘッダは,ある特定の表又はヒープの名前,位置及び長さを与える。ストリームヘッダ構造

体の長さは固定ではなく,名前フィールド(可変長の終端がナル文字の文字列。)の長さに依存することに

注意せよ。 

オフセット 

大きさ 

フィールド 

記述 

Offset 

メタデータの先頭(24.2.1参照)からこのストリームの起点
までのメモリオフセット。 

Size 

バイトで示されたストリームの大きさ。これは,4の倍数で
なければならない。 

Name 

ナル文字で終端したASCII 文字の可変長配列であるストリ
ームの名前。次の4バイト境界まで,文字 ” ¥0”で詰物する。
名前は32文字までに制限されている。 

論理的な表及びヒープの両方がストリームに格納される。可能なストリームは,5種類とする。名前

“#Strings”をもつストリームヘッダは,識別子文字列が格納される文字列ヒープの物理表現を指す。名前

“#US”をもつストリームヘッダは,利用者文字列ヒープの物理表現を指す。名前“#Blob”をもつストリ

ームヘッダは,ヒープblobの物理表現を指す。名前“#GUID”をもつストリームヘッダは,ヒープGUID

の物理表現を指す。また,名前“#~”をもつストリームヘッダは,一群の表の物理表現を指す。 

ストリームの各種類は,多くても一つまででなければならない。すなわち,メタデータファイルは,二

つの“#US”ストリーム又は五つの“#Blob”ストリームを含んではならない。ストリームが空であるなら

ば,存在しなくてもよい。 

24.2.3〜24.2.6で,各種類のストリームの構造体をより詳細に示す。 

24.2.3 #Stringsヒープ 

“#Strings”ヘッダが指すバイトストリームは,論理的な利用者文字列ヒープの物理的な表現とする。こ

の物理ヒープは,ごみ,すなわちどの表からも到達できない部分を含むことができるが,表から到達可能

な部分は,終端がナル文字列の有効なUTF8文字列を含まなければならない。#Stringヒープが存在する場

合,先頭要素は常に空文字列(すなわち¥0)とする。 

24.2.4 #US及び#Blobのヒープ 

“#US”ヘッダ又は“#Blob”ヘッダによって指されたバイトストリームは,それぞれ論理的な利用者文

字列ヒープ及び'blob'ヒープを物理的に表す。どれかの表から到達可能な部分が有効な'blob'を含んでいる限

り,両方のヒープはごみを含むことができる。個々のblobは,最初の数バイトに符号化された長さを格納

する。 

− 'blob'の最初の1バイトが0bbbbbbb2ならば,'blob'の残りはbbbbbbb2バイトの実データを含む。 

− 'blob'の最初の2バイトが10bbbbbb2及びxならば,'blob'の残りは,(bbbbbb2 << 8 + x)バイトの実デー

タを含む。 

background image

274 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

− 'blob'の最初の4バイトが110bbbbb2,x,y及びzならば,'blob'の残りは,(bbbbb2 << 24 + x << 16 + y << 

8 + z)バイトの実データを含む。 

これらの両方のヒープの最初の入口は,1バイトの0x00から成る,空の'blob'とする。 

#US(利用者文字列)ヒープ中の文字列は,16ビットUnicode符号化を用いる。各文字列の数値は,文

字列のバイト数(文字数ではない。)とする。さらに,追加の終端バイトがある(だからバイト数は,すべ

て偶数ではなく奇数になる。)。文字列内のいずれかのUTF16文字が,上位バイトのどれかのビットが立っ

ているか又はその下位バイトが,0x01〜0x08,0x0E〜0x1F,0x27,0x2D,0x7Fのいずれかである場合及

びその場合に限り,最終バイトが値1をもつ。そうでなければ,最終バイトは値0とする。値1は,通常

の8ビット符号化集合に対する処理を超えた処理が必要になるUnicode文字の扱いにおいて,を示す。 

24.2.5 #GUIDヒープ 

ヘッダ“#GUID”は,128ビットのGUIDの列を指す。到達不能なGUIDが,ストリームに格納されて

いてもよい。 

24.2.6 #~ストリーム 

“#~”ストリームは,論理的なメタデータ表(箇条23参照)の実際の物理的な表現を含む。“#~”スト

リームは,次の表に示す最上位構造をもつ。 

オフセット 

大きさ 

フィールド 

記述 

予約済み 

予約済み,常に0(24.1参照)。 

MajorVersion 

表スキーマの主版。1とする(24.1参照)。 

MinorVersion 

表スキーマの副版。0とする(24.1参照)。 

HeapSizes 

ヒープの大きさを示すビットベクトル。 

予約済み 

予約済み,常に1(24.1参照)。 

Valid 

現在の表のビットベクトル。1であるビットの個数をnとする。 

16 

Sorted 

整列した表のビットベクトル。 

24 

4*n 

Rows 

各々の現在の表の行要素の個数を示す4バイトの符号なし整数n
個の配列。 

24+4*n 

Tables 

物理的な表の列。 

フィールドHeapSizesは,様々なヒープへの添字の幅を符号化したビットベクトルとする。ビット0が1

ならば,“#String”ヒープへの添字は4バイト幅とする。ビット1が1ならば,“#GUID”ヒープへの添字

は4バイト幅とする。ビット2が1ならば,“#Blob”ヒープへの添字は4バイト幅とする。逆に,ある特

定のヒープに対するHeapSizesビットが設定されていないならば,そのヒープへの添字は2バイト幅とす

る。 

ビット位置 

記述 

0x01 

“#String”ストリームの大きさ>= 216。 

0x02 

“#GUID”ストリームの大きさ>= 216。 

0x04 

“#Blob”ストリームの大きさ>= 216。 

フィールドValidは,このストリームに格納される各表用に設定されるビットをもつ64ビット幅のビッ

トベクトルとする。表から添字への対応付けは,箇条22の最初に与える。例えば,表DeclSecurityが論理

的なメタデータの中に存在する場合,ビットベクトルValidにおいて,ビット0x0eを設定するのが望まし

い。存在しない表のビットをValidに取り込むのは不当なので,0x2bより上のすべてのビットはゼロでな

ければならない。 

配列Rowsは,存在する各々の表の行要素の個数を含む。物理的なメタデータから論理的なメタデータ

の情報を復号化するとき,ビットベクトルValid中の1の個数が,配列Rows中の要素の個数を示す。 

background image

275 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

論理的な表の符号化で重大なことは,そのスキーマである。各表のスキーマは,箇条22中に与える。例

えば,添字0x02が割り当てられた表は,22.37の規定に従って,表TypeDefとなり,4バイト幅のフラグ,

ヒープStringへの添字,そのヒープStringへの別の添字,表TypeDef,TypeRef又はTypeSpecへの添字,

表Fieldへの添字及び表MethodDefへの添字の欄をもつ。 

スキーマ(C0,…,Cn-1)をもつn欄m行の表の物理的な表現は,各行要素の物理的な表現の連結とな

る。スキーマ(C0,…,Cn-1)を備えた行要素の物理的な表現は,各要素の物理的な表現の連結となる。

型Cをもつ欄eの物理的な表現は,次のように定義される。 

− eが定数ならば,それは,その欄の型C(つまり,型PropertyAttributesの2ビットマスク)に指定さ

れたバイト数を用いて格納される。 

− eがヒープGUID,'blob'又はヒープStringの中への添字ならば,フィールドHeapSizesで定義したよう

にバイト数を用いて格納される。 

− eが添字iの表の中への単純な添字ならば,表iが216未満の行要素をもつならば,2バイトで格納さ

れ,そうでなければ4バイトで格納される。 

− eがn個の可能な表t0, …tn-1の中から表tiを指す符号化添字ならば,表t0, …tn-1の行要素の最大個数が 

2(16 ‒ (log n))未満である場合,2バイトを用いて,e << (log n) | tag{ t0, …tn-1}[ ti]とし,そうでなければ4バ

イトを用いて格納される。{ t0, …tn-1}の有限個の対応タグのファミリを,次に定義する。物理的な行要

素の復号化には,この逆の対応付けが必要なことに注意せよ(例えば,表Constantの欄Parentは,表

Field,Param又はProperty中の行要素を添字指定する。実際の表は,0 => Field, 1 => Param,2 => Property

という値を用いて,数値の下位2ビットに符号化される。残りのビットは,添字指定されている実際

の行要素を保持する。例えば,値0x321は,表Paramの中の行要素番号0xC8を指す。)。 

TypeDefOrRef:タグを符号化する2ビット 

タグ 

TypeDef 

TypeRef 

TypeSpec 

HasConstant:タグを符号化する2ビット 

タグ 

Field 

Param 

Property 

HasCustomAttribute:タグを符号化する5ビット 

タグ 

MethodDef 

Field 

TypeRef 

TypeDef 

Param 

InterfaceImpl 

MemberRef 

Module 

Permission 

Property 

Event 

10 

StandAloneSig 

11 

ModuleRef 

12 

background image

276 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

TypeSpec 

13 

Assembly 

14 

AssemblyRef 

15 

File 

16 

ExportedType 

17 

ManifestResource 

18 

HasFieldMarshall:タグを符号化する1ビット 

タグ 

Field 

Param 

HasDeclSecurity:タグを符号化する2ビット 

タグ 

TypeDef 

MethodDef 

Assembly 

MemberRefParent:タグを符号化する3ビット 

タグ 

TypeDef 

TypeRef 

ModuleRef 

MethodDef 

TypeSpec 

HasSemantics:タグを符号化する1ビット 

タグ 

Event 

Property 

MethodDefOrRef:タグを符号化する1ビット 

タグ 

MethodDef 

MemberRef 

MemberForwarded:タグを符号化する1ビット 

タグ 

Field 

MethodDef 

実装:タグを符号化する2ビット 

タグ 

File 

AssemblyRef 

ExportedType 

CustomAttributeType:タグを符号化する3ビット 

タグ 

使用されない 

使用されない 

MethodDef 

MemberRef 

使用されない 

background image

277 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

ResolutionScope: タグを符号化する2ビット 

タグ 

Module 

ModuleRef 

AssemblyRef 

TypeRef 

TypeOrMethodDef: タグを符号化する1ビット 

タグ 

TypeDef 

MethodDef 

25 PEへのファイル形式拡張 

CLI部品のファイル形式は,現在の可搬実行可能(PE)ファイル形式の拡張となる。この拡張PE形式

は,オペレーティングシステムが実行時イメージを認識できるようにし,CLI 又は プラットフォーム固

有コードとして発行したコードを提供し,発行されたコードとともに実行時メタデータをその一部として

提供する。ツール又はコンパイラが,有効なCLIイメージを発行するのに十分な詳細を含む,完全な

Windows PE/COFFファイル形式の部分集合用の規定も存在する。 

PE書式は,しばしばRVA(相対仮想アドレス)という用語を使用する。RVAは,メモリに一度ロード

された項目のアドレスとそこから差し引かれるイメージファイルの基底アドレスとからなる(すなわち,

ファイルがロードされる基底アドレスからのオフセット。)。ある項目のRVAは,ほとんど常に,ディスク

上のファイル内の位置とは異なる。RVA rの項目のファイル位置を計算するためには,PEファイル中のす

べてのセクションを検索して,RVA s長さlファイル位置pを備えたセクションで,そのRVAが存在する

ものを探索する。すなわち,s≦r<s+l。その項目のファイル位置は,p+(r−s)で与えられる。 

特に指定しない限り,すべての2進値は,下位バイト先行書式で格納される。 

25.1 実行時ファイル形式の構造体 

次の図は,CLIファイル形式を大まかに示す。実行時イメージは,次のすべてを含む。 

− PEヘッダ。実行時ファイル中でどのようにフィールド値を設定しなければならないかの規定を含む。 

− CLIヘッダ。これは,実行時のデータ要素をすべて含む。実行時ヘッダは,読込み専用で,読込み専

用セクションに置かれなければならない。 

− 実データを含むセクション。これは,移入,移出,データ及びコードを含めたヘッダによって記述さ

れる。 

CLIヘッダ(25.3.3参照)は,PEヘッダ中のCLIヘッダディレクトリエントリを用いて検索される。CLI

background image

278 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

ヘッダは,実行時データのアドレス及び大きさを含む(メタデータについては,箇条24,CILについては,

25.4を参照する。)。実行時データは,読み出し専用や実行などのようなセクション属性に基づいた他のデ

ータとともに,PE書式の他の領域へ結合可能なことに注意する。 

25.2 PEヘッダ 

PEイメージは,MS-DOSヘッダで始まり,PE識別情報,PEファイルヘッダと続く。最後に省略可能な

PEヘッダに続きPEセクションヘッダで終わる。 

25.2.1 MS-DOSヘッダ 

PE書式は,MS-DOSスタブで始まる。それは正確に次の128バイトであってモジュールの先頭に置かれ

る。MS-DOSヘッダ中のオフセット0x3cには,PE識別情報(“PE¥0¥0”とする。)に対する4バイトの符

号なし整数オフセットlfanewがあり,PEファイルヘッダが直後に続く。 

0x4d 

0x5A 

0x90 

0x00 

0x03 

0x00 

0x00 

0x00 

0x04 

0x00 

0x00 

0x00 

0xFF 

0xFF 

0x00 

0x00 

0xb8 

0x00 

0x00 

0x00 

0x00 

0x00 

0x00 

0x00 

0x40 

0x00 

0x00 

0x00 

0x00 

0x00 

0x00 

0x00 

0x00 

0x00 

0x00 

0x00 

0x00 

0x00 

0x00 

0x00 

0x00 

0x00 

0x00 

0x00 

0x00 

0x00 

0x00 

0x00 

0x00 

0x00 

0x00 

0x00 

0x00 

0x00 

0x00 

0x00 

0x00 

0x00 

0x00 

0x00 

Lfanew 

0x0e 

0x1f 

0xbA 

0x0e 

0x00 

0xb4 

0x09 

0xcd 

0x21 

0xb8 

0x01 

0x4c 

0xcd 

0x21 

0x54 

0x68 

0x69 

0x73 

0x20 

0x70 

0x72 

0x6f 

0x67 

0x72 

0x61 

0x6d 

0x20 

0x63 

0x61 

0x6e 

0x6e 

0x6f 

0x74 

0x20 

0x62 

0x65 

0x20 

0x72 

0x75 

0x6e 

0x20 

0x69 

0x6e 

0x20 

0x44 

0x4f 

0x53 

0x20 

0x6d 

0x6f 

0x64 

0x65 

0x2e 

0x0d 

0x0d 

0x0A 

0x24 

0x00 

0x00 

0x00 

0x00 

0x00 

0x00 

0x00 

25.2.2 PEファイルヘッダ 

PEファイルヘッダは,PE識別情報の直後にあり,次からなる。 

オフセット 

大きさ 

フィールド 

記述 

Machine 

常に0x14c(24.1参照)。 

Number of Sections 

セクションの個数。セクション表の大きさを示し,ヘッダ
の直後に続く。 

Time/Date Stamp 

ファイルが作成された,時刻及び日付。1970年1月1日00
時00分00秒を0として秒で表す。 

Pointer to Symbol Table 

常に0(24.1参照)。 

12 

Number of Symbols 

常に0(24.1参照)。 

16 

Optional Header Size 

省略可能なヘッダの大きさ。その書式は次で述べる。 

18 

Characteristics 

ファイルの属性を示すフラグ(25.2.2.1参照)。 

25.2.2.1 特徴 

CILだけからなるDLLは,フラグ0x2000を1に設定する,一方,CILだけからなる.exeは,フラグ0x2000

をゼロに設定する。 

フラグ 

値 

記述 

IMAGE̲FILE̲DLL 

0x2000 

イメージファイルはダイナミックリンクライブラリ(DLL)である。 

IMAGE̲FILE̲DLLフラグ(0x2000) を除いて,フラグ0x0002,0x0004,0x008,0x0100及び0x0020はす

べて設定されなければならず,一方,他のすべてはゼロでなければならない(24.1参照)。 

background image

279 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

25.2.3 省略可能なPEヘッダ 

PEヘッダの直後は,省略可能なPEヘッダとする。このヘッダは次の情報を含む。 

オフセット 

大きさ 

ヘッダ一部 

記述 

28 

標準フィールド 

PEファイルの一般的特性定義(25.2.3.1参照)。 

28 

68 

NTに特殊なフィール
ド 

Windowsの特殊な特徴を提供するために追加のフィールド
を取り込む(25.2.3.2参照)。 

96 

128 

データディレクトリ 

これらのフィールドは,イメージ ファイル(例えば移入表
及び移出表。)中に見られる特殊な表のためのアドレス/大
きさ対である。 

25.2.3.1 PEヘッダ標準フィールド 

これらのフィールドはすべてのPEファイルに必要であり,かつ次の情報を含む。 

オフセット 

大きさ 

フィールド 

記述 

Magic 

常に0x10B(24.1参照)。 

LMajor 

常に6(24.1参照)。 

LMinor 

常に6(24.1参照)。 

Code Size 

コード(テキスト)セクションの大きさ又は複数のセクシ
ョンがある場合,すべてのコードセクションの和。 

Initialized Data Size 

初期化データセクションの大きさ又は複数のデータセクシ
ョンがある場合,それらすべてのセクションの和。 

12 

Uninitialized Data Size 

未初期データセクションの大きさ又は複数の未初期データ
セクションがある場合,すべてのそのようなセクションの
和。 

16 

Entry Point RVA 

入口点のRVA,バイト列0xFF 0x25を指す必要がある。EXE
については,execute/readで印付けされたそのRVAの中の
セクションが続き,DLLについては0が続く。 

20 

Base Of Code 

コードセクションのRVA,exesについては常に,0x00400000
とし,DLLについては常に0x10000000とする。 

24 

Base Of Data 

データセクションのRVA(ローダにヒントを与える)。 

注記 ここから参考情報であり規定ではない。 

入口点RVAは常にx86入口点スタブであるか又は0でなければならない。非CLI上のプラットフォー

ムにおいては,このスタブが,mscoree(̲CorExeMain又は̲CorDllMain。)の入口点APIを呼び出す。mscoree

入口点は,イメージからのメタデータをロードし,かつ,CLIヘッダ中で指定された入口点を呼び出すた

めにモジュールハンドルを使用する。 

注記 参考情報終わり 

25.2.3.2 PEのヘッダのWindows NT特有フィールド 

これらのフィールドは,Windows NT特有とする。 

オフセット 

大きさ 

フィールド 

記述 

28 

Image Base 

常に0x400000(24.1参照)。 

32 

Section Alignment 

常に0x2000(24.1参照)。 

36 

File Alignment 

0x200又は0x1000のいずれか。 

40 

OS Major 

常に4(24.1参照)。 

42 

OS Minor 

常に0(24.1参照)。 

44 

User Major 

常に0(24.1参照)。 

46 

User Minor 

常に0(24.1参照)。 

48 

SubSys Major 

常に0(24.1参照)。 

50 

SubSys Minor 

常に0(24.1参照)。 

52 

Reserved 

常に0(24.1参照)。 

background image

280 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

56 

Image Size 

すべてのヘッダ及び詰め物を含むイメージのバイトで
の大きさ,セクション境界調整の倍数とする。 

60 

Header Size 

MS-DOSヘッダ,PEヘッダ,省略可能なPEヘッダ及
び詰め物の組み合わせられた大きさ,ファイル境界調
整の倍数とする。 

64 

File Checksum 

常に0(24.1参照)。 

68 

SubSystem 

このイメージの動作を要求する部分システム。
IMAGE̲SUBSYSTEM̲WINDOWS̲CE̲GUI(0x3)又は
IMAGE̲SUBSYSTEM̲WINDOWS̲GUI(0x2)のいずれ
かでなければならない。 

70 

DLL Flags 

常に0(24.1参照)。 

72 

Stack Reserve Size 

常に0x100000(1Mb)(24.1参照)。 

76 

Stack Commit Size 

常に0x1000(4Kb)(24.1参照)。 

80 

Heap Reserve Size 

常に0x100000(1Mb)(24.1参照)。 

84 

Heap Commit Size 

常に0x1000(4Kb)(24.1参照)。 

88 

Loader Flags 

常に0(24.1参照)。 

92 

Number of Data Directories 

常に0x10(24.1参照)。 

25.2.3.3 PEヘッダデータディレクトリ 

省略可能なヘッダデータディレクトリは,PEファイルのセクション中に現れる幾つかのアドレス及び大

きさを与える。データディレクトリ入口はそれぞれ,それが記述する構造体のRVA及びその順序での大き

さを含む。 

オフセット 

大きさ 

フィールド 

記述 

96 

Export Table 

常に0(24.1参照)。 

104 

Import Table 

移入表のRVA(24.3.1参照)。 

112 

Resource Table 

常に0(24.1参照)。 

120 

Exception Table 

常に0(24.1参照)。 

128 

Certificate Table 

常に0(24.1参照)。 

136 

Base Relocation Table 

再配置表,未使用である場合に0を設定(25.3.1参照)。 

144 

Debug 

常に0(24.1参照)。 

152 

Copyright 

常に0(24.1参照)。 

160 

Global Ptr 

常に0(24.1参照)。 

168 

TLS Table 

常に0(24.1参照)。 

176 

Load Config Table 

常に0(24.1参照)。 

184 

Bound Import 

常に0(24.1参照)。 

192 

IAT 

移入アドレス表のRVA(25.3.1参照)。 

200 

Delay Import Descriptor 

常に0(24.1参照)。 

208 

CLI Header 

実行時データ用ディレクトリを備えたCLIヘッダ
(25.3.1参照)。 

216 

Reserved 

常に0(24.1参照)。 

ディレクトリ入口によって指し示す表は,PEファイルのセクションに格納される。これらのセクション

はそれ自体セクションヘッダによって記述される。 

25.3 セクションヘッダ 

省略可能なヘッダに引き続いてセクション表があり,それは多くのセクションヘッダを含む。この位置

に関する要請は,ファイルヘッダがセクション表への直接のポインタを含んでいないことによる。セクシ

ョン表の場所は,ヘッダに後続する最初のバイトの場所を算出することによって決定される。 

各セクションヘッダは次の書式をもち,それぞれ一つの入口につき合計40バイトとする。 

オフセット 

大きさ 

フィールド 

記述 

background image

281 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

Name 

8バイト,nullが埋め込まれたASCII文字列。文字列の
長さがちょうど8文字である場合,終了null文字はな
い。 

VirtualSize 

メモリにロードされた場合の,セクションの合計の大
きさ。この値が生データの大きさより大きい場合,セ
クションにはゼロが埋め込まれる。 

12 

VirtualAddress 

実行可能なイメージについては,メモリにロードされ
た場合,これがセクションの先頭バイトの,イメージ
を基底とした相対での,アドレスとなる。 

16 

SizeOfRawData 

ディスク上の初期化データのバイトでの大きさ。それ
はPEヘッダからファイル境界の倍数でなければならな
い。これがVirtualSize未満である場合,セクションの
剰余は,ゼロが埋められる。このフィールドは丸めら
れるが,一方VirtualSizeフィールドは丸められないた
め,このフィールドは,VirtualSizeよりも大きくなるこ
とがある。セクションが初期化されていないデータだ
けを含んでいる場合,このフィールドは0となる。 

20 

PointerToRawData 

PEファイル内で,セクションの最初のページのオフセ
ット。これは省略可能なヘッダからのファイル境界の
倍数でなければならない。セクションが初期化されて
いないデータだけを含んでいる場合,このフィールド 
は0となる。 

24 

PointerToRelocations 

再配置セクションのRVA。 

28 

PointerToLinenumbers 常に0(24.1参照)。 

32 

NumberOfRelocations 再配置の個数,未使用である場合,0を設定。 

34 

NumberOfLinenumbers 常に0(24.1参照)。 

36 

Characteristics 

セクションの特徴について記述するフラグ(次を参
照)。 

次の表は,セクションの可能な特徴を定義する。 

フラグ 

値 

記述 

IMAGE̲SCN̲CNT̲CODE 

0x00000020 セクションは実行可能なコードを含む。 

IMAGE̲SCN̲CNT̲INITIALIZED̲DATA 

0x00000040 セクションは初期化データを含む。 

IMAGE̲SCN̲CNT̲UNINITIALIZED̲DATA 

0x00000080 セクションは初期化されていないデータを含

む。 

IMAGE̲SCN̲MEM̲EXECUTE 

0x20000000 セクションはコードとして実行可能とする。 

IMAGE̲SCN̲MEM̲READ 

0x40000000 セクションは読込み可能とする。 

IMAGE̲SCN̲MEM̲WRITE 

0x80000000 セクションは書込み可能とする。 

25.3.1 移入表及び移入アドレス表(IAT) 

移入表及び移入アドレス表(IAT)は実行時エンジン(mscoree.dll)の入口,(.exe用の)̲CorExeMain

又は(.dll用の)̲CorDllMainを移入するために使用される。移入表ディレクトリ入り口は,移入ディレ

クトリ入り口の,1要素でゼロ終端のポイントする(一般的なPEファイルでは,移入された各DLLに対

し一つの入口がある。)。 

オフセット 

大きさ 

フィールド 

記述 

ImportLookupTable 

移入検索表のRVA。 

DateTimeStamp 

常に0(24.1参照)。 

ForwarderChain 

常に0(24.1参照)。 

12 

Name 

Nullで終端したASCII文字列“mscoree.dll”のRVA。 

background image

282 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

16 

ImportAddressTable 

移入アドレス表のRVA(これは,省略可能なヘッダ中の
IAT記述子のRVAと同一となる)。 

20 

20 

移入表の終了。ゼロで埋められなければならない。 

移入検索表及び移入アドレス表(IAT)は,ともに1要素でゼロ終端の,RVAから連想表への配列とす

る。RVAの31ビット目は0に設定されなければならない。一般的なPEファイルでは,すべての移入され

た記号に対しこの表に一つの入口がある。 

オフセット 

大きさ 

フィールド 

記述 

Hint/Name Table RVA 

連想表への31ビットRVA。31ビット目は名前による移入
を示すため0に設定されなければならない。 

表の終了,ゼロで埋められなければならない。 

IATは実行可能,かつ,書込み可能なセクションになければならず,これはローダが連想表へのポイン

タを,移入された記号の実際の入口点に置き換えることで保証される。 

連想表は,ヒント及び移入されるDLL入口の名前からなる。 

オフセット 

大きさ 

フィールド 

記述 

Hint 

0とする。 

variable Name 

大文字と小文字とを区別しナル文字で終了するASCII文
字列。移入すべき名前を含む。.exeファイルについては
“̲CorExeMain”とし,.dllファイルについては
“̲CorDllMain”とする。 

25.3.2 再配置 

純粋なCILイメージでは,型IMAGE̲REL̲BASED̲HIGHLOW(0x3)をもつ単一のfixupはx86開始スタ

ブに必要となる。ここでスタブは,ダウンレベルローダ上の実行時エンジンをロードするためにIATにア

クセスする。CIL及びプラットフォーム固有の混合イメージを作成する場合又はイメージが利用者データ

内に埋込みRVAを含む場合,再配置セクションは同様にこれらのための再配置を含む。 

再配置は,“.reloc”という名前のそれら自身のセクションでなければならず,PEファイル中の最後のセ

クションでなければならない。再配置セクションは,fixup表を含む。フィックスアップ表はフィックスア

ップのブロックに分解される。それぞれのブロックは,4KBページのフィックスアップを表現し,それぞ

れのブロックは,32ビットの境界で始まらなくてはならない。 

それぞれのフィックスアップブロックは,次の構造体で始まる。 

オフセット 

大きさ 

フィールド 

記述 

PageRVA 

フィックスアップを適用する必要のあるブロックのRVA。
下位12ビットはゼロでなければならない。 

Block Size 

フィックスアップブロックのバイト数の合計。ページRVA
及びブロックの大きさフィールドを含む。引き続く型及び
オフセットフィールドも含む。大きさは,次の4の倍数で
丸められる。 

BlockSizeフィールドは,(BlockSiz−8)/2個の型/オフセットが続く。各入口はワード(2バイト)で,

次の構造をもつ(必要に応じて,長さを4バイトの倍数とするための2バイトの0が挿入される。)。 

オフセット 

大きさ 

フィールド 

記述 

4ビット 

Type 

語の上位4ビットを格納。値は,どの型のフィックスアッ
プが適用されることになっているか示す(前参照)。 

12ビット 

Offset 

語の残り12ビットを格納。ブロックのページRVAフィー
ルドに指定された開始アドレスからのオフセット。このオ
フセットは,フィックスアップがどこが適用されることに
なっているか明示する。 

background image

283 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

25.3.3 CLIヘッダ 

CLIヘッダは実行時に特有なデータ入口及び他の情報をすべて含む。ヘッダは,イメージの読出し専用

の共有可能なセクションに置かれる。このヘッダは次のとおり定義される。 

オフセット 

大きさ 

フィールド 

記述 

Cb 

バイトでのヘッダの大きさ。 

MajorRuntimeVersion 

このプログラムを動作させるのに必要な実行時環境の最
小の版,現在,2。 

MinorRuntimeVersion 

版のマイナー部分,現在,0。 

MetaData 

物理的なメタデータのRVA及び大きさ(箇条24参照)。 

16 

Flags 

この実行時イメージについて記述するフラグ。(25.3.3.1
参照)。 

20 

EntryPointToken 

イメージ用の入口点のMethodDef又はファイルのための
トークン。 

24 

Resources 

RVA及び実装固有資源の大きさ。 

32 

StrongNameSignature 

このPEファイル用のハッシュデータのRVA。CLIローダ
によって結合及び版管理のために使用される。 

40 

CodeManagerTable 

常に0(24.1参照)。 

48 

VTableFixups 

ファイル中のロケーション配列のRVA。関数ポインタの
配列(例えばvtableスロット。)を含む(次参照)。 

56 

ExportAddressTableJumps 常に0(24.1参照)。 

64 

ManagedNativeHeader 

常に0(24.1参照)。 

25.3.3.1 実行時フラグ 

次のフラグはこの実行時イメージについて記述し,ローダによって使用される。 

フラグ 

値 

記述 

COMIMAGE̲FLAGS̲ILONLY 

0x00000001 常に1(24.1参照)。 

COMIMAGE̲FLAGS̲32BITREQUIRED 

0x00000002 イメージは32ビットプロセスにだけロードで

きる。例えば,32ビットのvtablefixupsがある
場合又はプラットフォーム固有な整数から
int32へのキャストがある場合がそれに該当す
る。プラットフォーム固有な整数が64bitをもつ
CLI実装は,このフラグ集合をもつバイナリを
ロードしてはならない。 

COMIMAGE̲FLAGS̲STRONGNAMESIGNED 0x00000008 イメージは厳密な名前識別情報をもつ。 

COMIMAGE̲FLAGS̲TRACKDEBUGDATA 

0x00010000 常に0(24.1参照)。 

25.3.3.2 入口点メタデータトークン 

− マルチモジュールアセンブリ用の入口点が目録アセンブリにない場合,入口点トークン(15.4.1.2参照)

は常にMethodDefトークン(22.26参照)又はファイルトークン(22.19参照)とする。メソッド用メ

タデータ中の識別情報と実装のフラグは,入口がどのように動作されるか示す。 

25.3.3.3 Vtableフィックスアップ 

共通型システム実行時モデルに従わないような,言語では,v-tableの中で表現される必要のある仮想関

数をもっていてもよい。これらのv-tableはコンパイラによって配置されるのであって,実行時システムで

はない。正しいv-tableスロットを検索し,そのスロットの中に保持された値によって間接的に呼び出すこ

とも,コンパイラによって行われる。実行時ヘッダ中のVtableFixupsフィールドは,Vtable FIxupの配列

(15.5.1参照)の場所及び大きさを含む。Vtableは,PEファイルの読み書き可能セクションへ送られなけ

ればならない。 

background image

284 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

この配列中の入口はそれぞれ,特定の大きさのv-tableスロットの隣接した配列について記述する。スロ

ットはそれぞれ,それらが呼び出す必要のあるメソッドに対するメタデータトークン値に初期化されて起

動する。イメージをロードする時に,実行時ローダが,各入口をCPU用の機械コードへのポインタに変更

することによって直接的にメソッドを呼び出すことができる。 

オフセット 

大きさ 

フィールド 

記述 

VirtualAddress 

VtableのRVA。 

Size 

Vtable中の入口の個数。 

Type 

次のテーブルに定義された入口の型。 

定数 

値 

記述 

COR̲VTABLE̲32BIT 

0x01 

Vtableスロットは32ビットとする。 

COR̲VTABLE̲64BIT 

0x02 

Vtableスロットは64ビットとする。 

COR̲VTABLE̲FROM̲UNMANAGED 

0x04 

管理外から管理下コードへの推移。 

COR̲VTABLE̲CALL̲MOST̲DERIVED 0x10 

トークンによって記述された大部分の派生メソッド呼出
し(仮想メソッドに対してだけ有効。)。 

25.3.3.4 厳密な名前識別情報 

このヘッダ入口は,イメージ用の厳密な名前ハッシュを指す。ここでイメージは,参照地点(6.2.1.3参

照)からのモジュールを識別するために使用することができる。 

25.4 共通中間言語の物理的配置 

この細分箇条は,CILメソッド及びその例外について記述するために使用されるデータ構造の配置を含

む。メソッド本体は,PEファイルの任意の読込み専用セクションに格納することができる。メタデータ中

のMethodDef(22.26参照)レコードは各メソッドのRVAをもつ。 

メソッドは,次のものから構成される。すなわち,メソッドヘッダ,直後にメソッド本体が続く。続い

て,メソッドデータセクション(25.4.5参照),さらに,典型的には例外処理データが続くことがある。例

外処理データが存在する場合,CorILMethod̲MoreSectsフラグ(25.4.4参照)が,メソッドヘッダ中で,そ

れの後の各関連項目のために指定されなければならない。 

メソッドヘッダの二つの種類,極小(25.4.2参照)及び通常(25.4.3参照)がある。メソッドヘッダ中の

下位2ビット(LSB)は,どの型が存在するか示す(25.4.1参照)。極小ヘッダは,長さ1バイトで,メソ

ッドコードの大きさだけを格納する。メソッドは,局所変数をもっていない場合,極小ヘッダを与えられ

る。この場合,maxstackは8以下とし,メソッドは例外をもたず,メソッドの大きさは64バイト未満と

し,更に,メソッドは,0x7より上のフラグをもたない。通常ヘッダは完全な情報をもつ。すなわち,局

所変数識別情報トークン,maxstack,コードの大きさ,及びフラグのすべてをもつ。極小メソッドヘッダ

は,どのようなバイト境界でも開始することができる。通常メソッドヘッダは,4バイト境界になければ

ならない。 

25.4.1 メソッドヘッダ型の値 

メソッドヘッダの最初のバイトの下位2ビット(LSB)は,どの型のヘッダが存在するか示す。これら

の2ビットは次のうち一つの値だけを取り得る。 

値 

値 

記述 

CorILMethod̲TinyFormat 

0x2 

メソッドヘッダは,極小とする(25.4.2参照)。 

CorILMethod̲FatFormat 

0x3 

メソッドヘッダは,通常とする(25.4.3参照)。 

25.4.2 極小書式 

極小ヘッダは6ビット長の符号化を使用する。次はすべての極小ヘッダで成り立つ。 

background image

285 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

− 局所変数は許可されない。 

− 例外はない。 

− 追加データセクションはない。 

− 演算対象スタックは八つの入口分より大きくとる必要はない。 

極小書式ヘッダは,次の符号である。 

先頭ビット 

ビット数 

記述 

フラグ(CorILMethod̲TinyFormatを設定する,25.4.4参照)。 

このヘッダ直後のメソッド本体のバイトでの大きさ。 

25.4.3 通常書式 

極小書式が十分でない場合は,常に通常書式が使用される。そうなるのは,次のうち一つ以上が成り立

つ場合である。 

− メソッドは上の大きさ(64バイト)よりも大きいので,符号化できない。 

− 例外がある。 

− 追加データセクションがある。 

− 局所変数がある。 

− 演算対象スタックが八つを超える入口を必要とする。 

通常ヘッダは,次の構造をもつ。 

オフセット 

大きさ 

フィールド 

記述 

12(bits) 

Flags 

フラグ(CorILMethod̲FatFormatをビット0:1設定しなけれ
ばならない,25.4.4参照)。 

12 (bits) 

4(bits) 

Size 

このヘッダの大きさ。4バイト整数の大きさで丸められる。 

2  

2  

MaxStack 

演算対象スタック上の項目の最大数。 

CodeSize 

実際のメソッド本体のバイトでの大きさ。 

LocalVarSigTok メソッド用の局所変数の配置について記述する識別情報に

対応するメタデータトークン。0は,局所変数がないこと
を意味する。 

25.4.4 メソッドヘッダ用のフラグ 

メソッドヘッダの最初のバイトは,更に,次のフラグを含んでいてもよい。これらは,通常書式にだけ

有効であり,メソッドがどのようにして実行されるか示す。 

フラグ 

値 

記述 

CorILMethod̲FatFormat 

0x3 

メソッドヘッダは,通常とする。 

CorILMethod̲TinyFormat 

0x2 

メソッドヘッダは,極小 とする。 

CorILMethod̲MoreSects 

0x8 

セクションが,更にこのヘッダの後に続く(25.4.5参照)。 

CorILMethod̲InitLocals 

0x10 

すべての局所変数に対する省略時構築子呼出し。 

25.4.5 メソッドデータセクション 

メソッド本体に続く次の4バイトの境界には,追加メソッドデータセクションがあってもよい。これら

のメソッドデータセクションは,2バイトのヘッダ(フラグ用に1バイト,及び実データの長さ用に1バ

イト)又は4バイトのヘッダ(フラグ用に1バイト,及び実データの長さ用に3バイト)で始まる。最初

のバイトは,ヘッダの種類,及び実際のセクション中のデータが何かを指定する。 

フラグ 

値 

記述 

CorILMethod̲Sect̲EHTable 

0x1 

例外処理データ。 

CorILMethod̲Sect̲OptILTable 0x2 

予約済み,0でなければならない。 

background image

286 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

CorILMethod̲Sect̲FatFormat 

0x40 

データ形式は通常版,すなわちLSB形式3バイト長がある
ことを意味する。未設定である場合,小さい版,すなわち
ヘッダは1バイト長とする。 

CorILMethod̲Sect̲MoreSects 

0x80 

別のデータセクションが,現在のセクションの後に存在す
る。 

現在,メソッドデータセクションは例外表(箇条19参照)にだけ使用される。小さい版の例外ヘッダ構

造は,次のとおりとする。 

オフセット 

大きさ 

フィールド 

記述 

Kind 

上述のフラグ。 

DataSize 

ブロック用データの大きさ。ヘッダを含む,すなわちn*12+4と
なる。 

Reserved 

詰め物。常に0。 

Clauses 

n個の小さい版の例外節。(25.4.6参照)。 

通常版の例外ヘッダのレイアウトを次に示す。 

オフセット 

大きさ 

フィールド 

記述 

Kind 

どの型の例外ブロックが,使われているかを示す。 

DataSize 

ブロック用データの大きさ。すなわちn*24+4となる。 

Clauses 

n個の通常版の例外節(25.4.6参照)。 

25.4.6 例外処理節 

例外処理節は,小さな版及び通常版の双方にある。 

tryブロック及びハンドラコードの合計の大きさが256バイト以下であり,そしてそれらのオフセットが,

65536.未満である場合は常に,小さい版の例外節を使うことを推奨する。小さい版の例外節の書式は次の

とおりとする。 

オフセット 

大きさ 

フィールド 

記述 

Flags 

フラグ(次を参照)。 

TryOffset 

ヘッダ先頭からのtryブロックのバイトオフセット。 

TryLength 

tryブロックのバイトので長さ。 

HandlerOffset 

このtryブロック用のハンドラの場所。 

HandlerLength 

ハンドラコードのバイトでの大きさ。 

ClassToken 

型に基づく例外ハンドラ用のメタデータトークン。 

FilterOffset 

フィルタに基づく例外ハンドラに対するメソッド本体中のオフセ
ット。 

例外処理節の通常形式の配置は次のとおりとする。 

オフセット 

大きさ 

フィールド 

記述 

Flags 

フラグ(次を参照)。 

TryOffset 

メソッド本体からのtryブロックのバイトオフセット。 

TryLength 

tryブロックのバイトでの長さ。 

12 

HandlerOffset 

このtryブロック用のハンドラの場所。 

16 

HandlerLength 

バイトでのハンドラコードの大きさ。 

20 

ClassToken 

型に基づく例外ハンドラ用のメタデータトークン。 

20 

FilterOffset 

フィルタに基づく例外ハンドラに対するメソッド本体中のオフセ
ット。 

次のフラグ値が各例外処理節に使用される。 

フラグ 

値 

記述 

COR̲ILEXCEPTION̲CLAUSE̲EXCEPTION 

0x0000 型付きの例外節。 

COR̲ILEXCEPTION̲CLAUSE̲FILTER 

0x0001 例外フィルタ及びハンドラ節。 

COR̲ILEXCEPTION̲CLAUSE̲FINALLY 

0x0002 finally節。 

background image

287 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

COR̲ILEXCEPTION̲CLAUSE̲FAULT 

0x0004 違反節(最終的にそれは例外でだけ呼び出され

る。)。 

第3章 CIL命令集合 

有効範囲 

この章は,共通言語基盤の仕様の一部である共通中間言語(Common Intermediate Language;CIL)命令

集合の詳細を定義する。第1章は,CLIのアーキテクチャについて定義しており,CIL命令集合に関連す

る多くの論題の概要を提示している。その概要は,ここで定義する命令集合の理解に必要となる。 

この章では,各命令をそれぞれ一つの箇条で説明する。各々の命令の定義は,関連するCLI計算機命令

群も同時に定義する。各々の命令の定義は次の部分からなる。 

− バイナリ形式を定義する表,アセンブリ言語の表記法及び命令の各変異形の定義(1.2参照)。 

− 命令が実行される前と実行された後の評価スタックの状態を定義するスタック遷移図(1.3参照)。 

− 日本語による命令の定義(1.4参照)。 

− 命令が送出する可能性のある例外(第1章参照)の一覧。次の三つの例外は,すべての命令が送出す

る可能性があるため,各命令の定義の箇所には挙げない。 

System.ExecutionEngineExceptionは,実行エンジンの内部状態が悪くなり,実行が続ける

ことができないことを示す。 

注記 正当性検証可能なコードだけを実行するシステムでは,この例外は送出されない。 

System.StackOverflowExceptionは,ハードウェアのスタックの大きさを超過したことを示

す。この例外が送出される正確なタイミング及びこの例外が発生する条件は,実装固有とする。 

注記 この例外は1.7.4で定義する最大スタックの大きさとは無関係とする。ハードウェアのスタ

ックの大きさは,第1章で定義するメソッド状態の一部である評価スタックの深さと関係

するため,この例外は物理的なハードウェア上のメソッド状態の実装と関係する。 

System.OutOfMemoryExceptionは,利用可能なメモリ空間を使い切ったことを示す。これは命

令が本質的にメモリ割当てを行うものである(newobj,newarr。)か又は実装固有の理由のいずれ

かによって生じる。例えば,プラットフォーム固有のコードへのJITを行うことを基本とした実装で

ある場合,指定されたメソッドに対する初回のcall又はcallvirtを実行中に,解釈したメソッド

を格納するための領域を使い切ってしまう可能性がある。 

− 命令に関連付けられた正当性検証可能性条件について記述する箇条(1.8参照)。 

さらに,数値の演算対象をもつ演算については,演算対象の型に基づいてどのように演算を行うかを規

定する演算対象の型の表も示す。 

すべてのCLIプロファイルがすべての命令を含んでいるとは限らないことに注意する(第4章参照)。 

1.1 

データ型 

CTSが豊富な型のシステムを定義し,CLSが,言語相互運用性に対して使用できる型の部分集合を規定

するのに対し,CLI自体は型についてはるかに単純な集合を扱う。これらの型は利用者定義の値型及び組

込み型の部分集合を含む。この部分集合を,集合的に“基本CLI型”と呼ぶ。次に基本CLI型を示す。 

− すべての数値型(int32,int64,native int及びF)の部分集合。 

− 参照しているオブジェクトの型を区別しないオブジェクト参照(O)。 

− ポイント先の型を区別しないポインタ型(native unsigned int及び&。)。 

オブジェクト参照及びポインタ型に値nullを代入できることに注意する。CLIでは一貫してnullを0

288 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

(すべてのビットが0のビットパターン。)と定義する。 

1.1.1 

数値データ型 

− CLIは,数値型int32(4バイト符号付き整数。),int64(8バイト符号付き整数。),native int

(プラットフォーム固有の大きさの整数)及びF(プラットフォーム固有の大きさの浮動小数点数)

に対してだけ効果をもつ。しかし,CIL命令集合は,追加のデータ型を実装することを許す。 

− 短整数。評価スタックが保持するのは,4バイト整数又は8バイト整数だけとする。しかし,他の場

所(実引数,局所変数,静的メンバ,配列の要素,フィールド。)は1バイト整数又は2バイト整数を

保持できる。これらの場所からスタック上にロードする時は,ゼロ拡張(ldind.u*,ldelem.u*な

ど)又は符号拡張(ldind.i*,ldelem.i*など)による4バイト値への変換が行われる。短整数へ

格納(stind. i1,stelem.i2など)する時には切捨てが発生する。切捨てによって元の値を正し

く表現しない値になった場合,conv.ovf.*命令によって検出可能とする。 

注記 短整数(すなわち1バイト又は2バイトの整数)は,すべてのアーキテクチャにおいて,4バ

イトの数値としてロードされる。これらの4バイトの数値は常に8バイトの数値とは区別して

追跡されなければならない。これによって,省略時の算術演算の動作がすべての実装において

一致することを保証することで,コードの可搬性を高める。 

短整数値を生成する変換命令は,実際にはスタックにint32(32ビット)値を残すが,下位ビットだけ

が意味をもつことを保証する(すなわち,上位ビットは,符号なし変換に対してはすべてゼロになってお

り,符号付き変換に対しては符号拡張になっている。)。正確に短整数演算の完全な集合を模擬するために

は,div,rem,shr,比較及び条件付き分岐命令の前に,短整数への変換が必要となる。 

明示的な変換命令のほかに,次の四つの場合には,CLIは特殊な方法で短整数を扱う。 

1) 短整数型で宣言された型の局所変数への代入(stloc)及び実引数への代入(starg)では,自動

的に,その局所変数又は実引数に対して指定された大きさに切り捨てられる。 

2) 短整数型で宣言された型の局所変数からのロード(ldloc)及び実引数からのロード(ldarg)で

は,自動的に符号拡張が行われる。 

3) 短整数型の実引数をもつ手続の呼出しは,実引数値への代入と同等とする。したがって,切捨てが

行われる。 

4) 返却値の型が短整数であるメソッドからの値の返却は,呼び出される側の手続内では短整数への格

納をモデルとし(すなわち,CLIは自動的に切捨てを行う。),呼び出す側の手続内では短整数から

のロードをモデルとする(すなわち,CILは自動的にゼロ拡張又は符号拡張を行う。)。 

最後の二つの場合には,切捨て及び拡張が呼び出される側の手続内で行われるか,呼び出す側の手続内

で行われるかと同様に,実際に値を切り捨てるかどうか及び拡張するかどうかの決定はプラットフォーム

固有の呼出し規約に依存する。CIL命令列は影響を受けず,あたかもCIL命令列が適切なconv命令を含

んでいるかのように動作する。 

− 4バイト整数。スタック上に実際に格納される最も短い値は4バイト整数とする。4バイト整数は

conv.*命令を使って8バイトの整数又はプラットフォーム固有の大きさの整数に変換できる。プラ

ットフォーム固有の大きさの整数は4バイトの整数に変換できるが,この変換はアーキテクチャ間で

可搬ではない。超過する上位ビットを無視する場合,この変換にはconv.i4及びconv.u4が使用で

きる。情報の損失の検出には,conv.ovf.i4及びconv.ovf.u4命令を使用できる。算術演算は,4

バイト整数とプラットフォーム固有の大きさの整数との組合せを許容し,結果としてプラットフォー

ム固有の大きさの整数を生成する。4バイト整数は,8バイト整数とは直接組み合わせることはできな

289 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

い(事前に4バイト整数を8バイト整数に変換しておかなければならない。)。 

− プラットフォーム固有の大きさの整数。プラットフォーム固有の大きさの整数は,通常の算術命令の

いずれを使用する場合でも,4バイト整数と組み合わせることができ,結果はプラットフォーム固有

の大きさの整数になる。8バイト整数と組み合わせる場合には,あらかじめプラットフォーム固有の

大きさの整数を明示的に8バイト整数に変換しておかなければならない。 

− 8バイトの整数。32ビットのハードウェアにおいて8バイト整数に対応することは多大な労力がかか

るかもしれない。一方,64ビットのハードウェアにおいては,32ビット算術演算が使用可能で,効率

もよい。したがって,数値演算命令はint32及びIを混合して用いてもよい(入力として使われた最

大の型を生成する。)。しかし,これらの型はint64と組み合わせて使用することはできない。native 

int又はint32とint64とを組み合わせて使用する場合,使用する前に明示的にint64に変換し

なければならない。 

− 符号なし整数。特殊命令は,スタック位置に符号なし整数であるというタグをつけるのではなく,あ

たかも符号なし整数であるかのようにスタック上の整数を解釈するために使われる。 

− 浮動小数点数。第1章,浮動小数点数データ型の処理参照。浮動小数点数に対する記憶域の場所(静

的変数,配列の要素及びクラスのフィールド。)は固定の大きさとする。対応する記憶域の大きさは

float32及びfloat64とする。その他の場所(評価スタック上で,実引数として,返却値の型とし

て,及び局所変数として。)では,浮動小数点数は内部浮動小数点数型を使って表現される。個々のそ

のようなインスタンスでは,変数又は式の名目上の型はfloat32又はfloat64のいずれかとする。

しかし,その値は内部的には追加の値域及び/又は精度で表現してもよい。内部浮動小数点数表現の

大きさは実装依存で,実装ごとに異なっているかもしれないが,少なくとも表現されている変数又は

式の精度と同じ大きさでなければならない。float32又はfloat64から内部表現への暗黙の拡大変

換は,これらの型が記憶域からロードされる時に実行される。内部処理形式は,典型的にはハードウ

ェアに自然な大きさになっているか,又は演算の効率のよい実装を行うために必要な大きさになって

いる。内部処理形式は次の特質をもたなければならない。 

− 内部表現形式の精度及び範囲は,名目上の型と等しいか又はそれより大きくなければならない。 

− 内部処理形式からの変換及び内部処理形式への変換は,値を保存しなければならない。 

注記 

これは,float32(又はfloat64。)から内部処理形式への暗黙の拡大変換を行った後,

内部処理形式からfloat32(又はfloat64。)への明示的な変換を行うと,元のfloat32

(又はfloat64。)の値と同じ値になることを意味する。 

注記 

上の規定は,規格適合処理系が中間計算において代入先の型の精度へと丸めることを避け,

縮約形命令のような,同じかより高い精度をもつ命令に変換する最適化変換を適用すること,

及びより高い精度をもつハードウェアのレジスタを使用することを許す。言語及びアプリケ

ーションによって,(例えばカーン求和公式のような)正確に再現可能な動作の精度が要求さ

れる場合には,明示的な変換を用いることができる。しかし,再現可能な精度は再現可能な

動作を保障するわけではない。超過精度を使った実装は2重に丸め処理を行うかもしれない。

すなわち浮動小数点数演算時に1回丸め処理を行い,明示的な変換の時に再度丸め処理を行

うかもしれない。超過精度を使わない実装では実質的には丸め処理は1回だけしか行われな

い。珍しいケースではあるが,2重に丸め処理を行う場合と1回しか丸め処理を行わない場

合では,最小精度の1単位分だけ異なる結果を導出する可能性がある。 

内部処理形式が名目上の型より広い値域及び高い精度をもつ浮動小数点数値が記憶域の場所におか

290 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

れる場合,その記憶域の場所の型に自動的に強制変換される。このとき精度の損失が起こったり,範

囲外の値(NaN,+無限大又は−無限大。)が生成されたりするかもしれない。しかし,将来その値を

一度も変更しないうちに記憶域の場所から再度ロードする場合に備えて,その値を内部処理形式のま

まかもしれない。後続のロードの時に,別名によるアクセス及び他の実行スレッドによる影響を考慮

しながら(メモリモデルの箇条を参照する。),そのメモリ位置がまだ有効かどうかを検証するのはコ

ンパイラの責任とする。しかし,明示的な変換(conv.r4又はconv.r8。)の実行後に,余分な精度

を保持し続けてはならず,明示的な変換後は,内部処理形式は関連づけられた型で正確に表現可能な

値でなければならない。 

注記 

特定の記憶域の型に変換できない値を検出するためには,変換命令(conv.r4及び

conv.r8。)を使用した後ckfiniteを使用しなければならない。特定の記憶域の型への変

換時のアンダフローを検出するためには,その変換の前後でゼロと比較しなければならない。 

注記 

この規格は非正規形の浮動小数点数の算術演算の動作を規定しない。また,非正規形の浮動

小数点数を生成するのが望ましいかどうか,及びどんな場合に非正規形の浮動小数点数を生

成するのが望ましいかも規定しない。これについてはIEC 60559:1989に従う。さらに,この

規格は生成されたNaNの正確なビットパターンにアクセスする方法を規定しない。また,

NaNを32ビット表現と64ビット表現との間で変換した場合の動作についても規定しない。

これらの動作はすべて故意に実装固有として保留してある。 

1.1.2 

Boolean型 

CLI論理型はメモリ中で1バイトを占有する。全ビットがゼロのビットパターンは偽を示す。一つ以上

の任意のビットが設定されている(0でない整数と類似した。)ビットパターンは真を示す。 

1.1.3 

オブジェクト参照 

オブジェクト参照(O型)は完全に非透過的とする。演算対象としてオブジェクト参照を許す算術命令

はない。また,許される比較演算は,二つのオブジェクト参照間の等価演算(及び非等価演算。)だけとす

る。オブジェクト参照について定義された変換演算はない。オブジェクト参照は,CILオブジェクト命令

(特にnewobj及びnewarr。)によって生成される。オブジェクト参照は,実引数として渡すこと,局所

変数として格納すること,値として返却すること,配列に格納すること及びオブジェクトのフィールドと

して格納することができる。 

1.1.4 

実行時ポインタ型 

ポインタには,管理下ポインタと管理外ポインタの2種類がある。同じ配列又はオブジェクト(第1章

参照)へのポインタのために,次の算術演算を定義する。 

− ポインタへの整数の加算。整数はバイト数として解釈され,結果は同じ種類のポインタとなる。 

− ポインタからの整数の減算。結果は同じ種類のポインタとなる。整数からポインタを減算することは

許されていないことに注意する。 

− 種類に関係なく,二つのポインタは互いに減算でき,それらが参照するアドレス間のバイト数を示す

符号付き整数を生成する。 

これらの操作はいずれも正当性検証可能なコードの中では使用できない。 

異なる種類のポインタに対して算術演算を使用することのごみ集め子への影響を理解することは重要で

ある。管理外ポインタはごみ集め子によって制御されるメモリを参照してはならないため,管理外ポイン

タに対して算術演算を実行することはシステムのメモリの安全性を害する(したがって,それは正当性検

証可能でない。)にもかかわらず,管理外ポインタはごみ集め子に通知されないため,演算は問題なく実行

291 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

できる。 

しかし,管理下ポインタはごみ集め子に報告される。ごみ集めの一部として,管理下ポインタが指す位

置の内容及びポインタ自体のいずれも変更可能とする。ごみ集め子は,管理下ポインタが自身の管理下に

ないメモリ(評価スタック,呼出しスタック,静的メモリ,別のメモリ割当て機構の管理下にあるメモリ。)

を指しているとき,その管理下ポインタを無視する。しかし,管理下ポインタがごみ集め子の管理するメ

モリを参照している場合,その管理下ポインタは,オブジェクトのフィールド,配列の要素又は配列終端

直後の要素のアドレスのいずれかを指していなければならない。アドレス演算がそれ以外の位置(オブジ

ェクトヘッダ又は割り付けられたメモリ中のすき間。)を参照する管理下ポインタを作成するために使われ

る場合,ごみ集め子の動作は未規定とする。 

1.1.4.1 

管理外ポインタ 

管理外ポインタは,C及びC++のような言語で使われる伝統的なポインタとする。管理外ポインタは多

くの場合,正当性検証可能でないコードを生じるにもかかわらず,管理外ポインタの使用については全く

制限がない。管理外ポインタを含む位置にその管理外ポインタがあたかも符号なし整数であるかのように

(実際CLIは管理外ポインタを符号なし整数として扱う。)印付けることは完全に妥当であるが,多くの

場合,データの特定の型への管理外ポインタとして印付けるほうがよい。これは,返却値,局所変数若し

くは実引数に対する識別情報中のELEMENT̲TYPE̲PTRを使うことによって実現されるか,又はフィール

ド若しくは配列要素に対するポインタ型を使うことによって実現される。 

管理外ポインタはごみ集め子に報告されず,整数で使用できる任意の方法で使用できる。 

− 管理外ポインタは,符号なしとみなして扱うのが望ましい(すなわちconv.ovf.iなどではなく,

conv.ovf.uを使うことが望ましい。)。 

− 正当性検証可能なコードは,参照メモリへの管理外ポインタを使用できない。 

− 正当性検証可能でないコードは,管理下ポインタを期待するメソッドに管理外ポインタを渡すことが

できる。これは次の項目の一つが真である場合にだけ,安全とする。 

a) その管理外ポインタが,ごみ集め子の管理するメモリでないメモリを参照している。 

b) その管理外ポインタが,オブジェクト内のフィールドを参照している。 

c) その管理外ポインタが,配列内の要素を参照している。 

d) その管理外ポインタが,配列中の最後の要素に続く要素が配置される場所を参照している。 

1.1.4.2 

管理下ポインタ(型&) 

管理下ポインタ(&)は,局所変数,メソッド実引数,オブジェクトのフィールド,値型のフィールド,

配列の要素,静的フィールド又は(管理下配列を指すポインタに対しては)配列の終端直後の要素を格納

するアドレスを指してもよい。管理下ポインタはnullになりえない(管理下ポインタについては,その

管理下ポインタが管理下メモリを指していなくても,ごみ集め子に報告されなければならない。)。 

管理下ポインタは,返却値,局所変数若しくは実引数に対する識別情報中のELEMENT̲TYPE̲BYREFを

使って指定するか,又は,フィールド若しくは配列要素に対するby-ref型を使って指定する。 

− 管理下ポインタは実引数として渡すこと,及び局所変数に格納することができる。 

− 参照渡しで仮引数を渡した場合,対応する実引数は管理下ポインタとする。 

− 管理下ポインタを,静的変数,配列要素,オブジェクト型のフィールド及び値型のフィールドに格納

することはできない。 

− 管理下ポインタはオブジェクト参照と交換可能ではない。 

− 管理下ポインタは別の管理下ポインタを指すことはできない。しかし,管理下ポインタはオブジェク

background image

292 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

ト参照又は値型を指すことができる。 

− 管理下メモリを指さない管理下ポインタは,(conv.u又はconv.ovf.uを使って)管理外ポインタ

に変換できる。ただし,この変換を行うと正当性検証可能ではなくなる。 

− 管理下ポインタを誤って管理外ポインタに変換する正当性検証可能でないコードは,CLIの完全性に

深刻な欠陥を生じさせる可能性がある。次の項目のいずれかが真であると分かっている場合,この変

換は安全とする。 

a) 管理下ポインタがごみ集め子の管理するメモリ領域を指していない。 

b) 指されているメモリが,管理外ポインタが使用されている全期間にわたって固定されている。 

c) 管理外ポインタが使用されている間,ごみ集めが起こり得ない。 

d) CLIの特定の実装に対するごみ集め子が,参照されているメモリを移動しないことが分かっ

ている。 

1.2 

命令変異形の表 

箇条3で,各命令について,命令変異形の表を示す。命令変異形の表は,命令の各々の変異形について

定義する。命令変異形の表の形式の欄は,その命令変異形のオプコード,命令ストリームの中でその命令

に続く演算対象を提示する。次に例を示す。 

形式 

アセンブリ形式 

定義 

FE 0A <unsigned int16> ldarga ≪引数番号≫ 

≪引数番号≫の実引数のアドレスを取り出す。 

0F < unsigned int8> 

ldarga.s ≪引数番号≫ ≪引数番号≫の実引数のアドレスを取り出す。短縮形式。 

形式欄の先頭1けた又は2けたの16進数はこの命令がどのように符号化されているか(その“オプコー

ド”)を示す。例えば,ldarga命令は,FEを保持するバイト,及びそれに続く0Aを保持するもう一つの

バイトとして符号化される。“<”と“>”で囲まれた部分の型名は,命令ストリーム中で次に続くバイト

数の型を表す。この例では,オプコードFE 0Aの直後に,符号なし整数として扱われる2バイトが続く。 

例 ldc.<type>命令の形式の一つは,ldc.r8 numであり,この命令は“23 <float64>”という形式をもっ

ている。ldc.r8 3.1415926535897931という命令をコード化した結果は23 182D4454FB210940とな

る。ここで,182D4454FB210940は3.1415926535897931の8バイト16進表現である。 

同様に,ldc.<type>の他の形式に,ldc.i4.s numがあり,この命令は“1F <int8>”という形

式をもっている。ldc.i4.s -3という命令をコード化した結果は,1F FDとなる。ここで,FDは

-3の1バイト16進表現である。接尾辞.sは命令が短縮形式 の命令であることを示す。この例で

は,長い形式の命令であるldc.i4が5バイト必要なのに対して,短い形式のldc.i4.sは2バ

イトだけを必要とする。 

固定の大きさの組込み型(int8,unsigned int8,int16,unsigned int16,int32,unsigned 

int32,int64,unsigned int64,float32及びfloat64。)のいずれも,形式欄の記述に現れる可

能性がある。これらの型は,演算対象のバイト数及びその演算対象をどのように解釈するか(符号付き,

符号なし及び浮動小数点数のいずれと解釈するか。)を定義する。さらに,メタデータトークンが現れるこ

とがあり,<T>と示される。トークンは4バイトの整数として符号化される。すべての演算対象の値は最

下位バイトが最も小さなアドレスに格納される形式(一般に“リトルエンディアン”と呼ばれる形式。)で

符号化される。命令のオプコード及び実引数のバイト列は,可能な限り密に充てんされる(境界調整のた

めの詰物は一切行わない。)。 

アセンブリ形式欄は,各命令変異形のアセンブリコードのニーモニックを定義する。先の例のように命

293 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

令ストリームの演算対象をもつ命令については,アセンブリ形式欄はその命令の演算対象のそれぞれに名

前を割り当てる。命令の各々の演算対象に対して,アセンブリ形式欄の中で一つの名前が与えられる。こ

れらの名前は後で命令の定義の中で使われる。 

1.2.1 

オプコード符号化 

CILオプコードは1バイト以上であり,0バイト以上の演算対象が続くことがある。第1のバイトが0x00

から0xEF又は0xFCから0xFFの範囲内のオプコードは,標準化のために予約済みとなっている。第1の

バイトが両端を含んで0xF0から0xFBのオプコードは,実験的な目的に使用できる。任意のメソッド中の

実験的なオプコードの使用は,そのメソッドを不当なものにし,その結果正当性検証可能でないメソッド

となる。 

現在定義済みの符号化形式を,表1 オプコード符号化に列挙する。 

background image

294 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

表1−オプコード符号化 

オプコード 

命令 

0x00 

nop 

0x01 

break 

0x02 

ldarg.0 

0x03 

ldarg.1 

0x04 

ldarg.2 

0x05 

ldarg.3 

0x06 

ldloc.0 

0x07 

ldloc.1 

0x08 

ldloc.2 

0x09 

ldloc.3 

0x0A 

stloc.0 

0x0B 

stloc.1 

0x0C 

stloc.2 

0x0D 

stloc.3 

0x0E 

ldarg.s 

0x0F 

ldarga.s 

0x10 

starg.s 

0x11 

ldloc.s 

0x12 

ldloca.s 

0x13 

stloc.s 

0x14 

ldnull 

0x15 

ldc.i4.m1 

0x16 

ldc.i4.0 

0x17 

ldc.i4.1 

0x18 

ldc.i4.2 

0x19 

ldc.i4.3 

0x1A 

ldc.i4.4 

0x1B 

ldc.i4.5 

0x1C 

ldc.i4.6 

0x1D 

ldc.i4.7 

0x1E 

ldc.i4.8 

0x1F 

ldc.i4.s 

0x20 

ldc.i4 

0x21 

ldc.i8 

0x22 

ldc.r4 

0x23 

ldc.r8 

0x25 

dup 

0x26 

pop 

0x27 

jmp 

0x28 

call 

0x29 

calli 

0x2A 

ret 

0x2B 

br.s 

0x2C 

brfalse.s 

0x2D 

brtrue.s 

0x2E 

beq.s 

オプコード 

命令 

0x2F 

bge.s 

0x30 

bgt.s 

0x31 

ble.s 

0x32 

blt.s 

0x33 

bne.un.s 

0x34 

bge.un.s 

0x35 

bgt.un.s 

0x36 

ble.un.s 

0x37 

blt.un.s 

0x38 

br 

0x39 

brfalse 

0x3A 

brtrue 

0x3B 

beq 

0x3C 

bge 

0x3D 

bgt 

0x3E 

ble 

0x3F 

blt 

0x40 

bne.un 

0x41 

bge.un 

0x42 

bgt.un 

0x43 

ble.un 

0x44 

blt.un 

0x45 

switch 

0x46 

ldind.i1 

0x47 

ldind.u1 

0x48 

ldind.i2 

0x49 

ldind.u2 

0x4A 

ldind.i4 

0x4B 

ldind.u4 

0x4C 

ldind.i8 

0x4D 

ldind.i 

0x4E 

ldind.r4 

0x4F 

ldind.r8 

0x50 

ldind.ref 

0x51 

stind.ref 

0x52 

stind.i1 

0x53 

stind.i2 

0x54 

stind.i4 

0x55 

stind.i8 

0x56 

stind.r4 

0x57 

stind.r8 

0x58 

add 

0x59 

sub 

0x5A 

mul 

0x5B 

div 

0x5C 

div.un 

0x5D 

rem 

0x5E 

rem.un 

background image

295 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

オプコード 

命令 

0x5F 

and 

0x60 

or 

0x61 

xor 

0x62 

shl 

0x63 

shr 

0x64 

shr.un 

0x65 

neg 

0x66 

not 

0x67 

conv.i1 

0x68 

conv.i2 

0x69 

conv.i4 

0x6A 

conv.i8 

0x6B 

conv.r4 

0x6C 

conv.r8 

0x6D 

conv.u4 

0x6E 

conv.u8 

0x6F 

callvirt 

0x70 

cpobj 

0x71 

ldobj 

0x72 

ldstr 

0x73 

newobj 

0x74 

castclass 

0x75 

isinst 

0x76 

conv.r.un 

0x79 

unbox 

0x7A 

throw 

0x7B 

ldfld 

0x7C 

ldflda 

0x7D 

stfld 

0x7E 

ldsfld 

0x7F 

ldsflda 

0x80 

stsfld 

0x81 

stobj 

0x82 

conv.ovf.i1.un 

0x83 

conv.ovf.i2.un 

0x84 

conv.ovf.i4.un 

0x85 

conv.ovf.i8.un 

0x86 

conv.ovf.u1.un 

0x87 

conv.ovf.u2.un 

0x88 

conv.ovf.u4.un 

0x89 

conv.ovf.u8.un 

0x8A 

conv.ovf.i.un 

0x8B 

conv.ovf.u.un 

0x8C 

box 

0x8D 

newarr 

0x8E 

ldlen 

0x8F 

ldelema 

0x90 

ldelem.i1 

オプコード 

命令 

0x91 

ldelem.u1 

0x92 

ldelem.i2 

0x93 

ldelem.u2 

0x94 

ldelem.i4 

0x95 

ldelem.u4 

0x96 

ldelem.i8 

0x97 

ldelem.i 

0x98 

ldelem.r4 

0x99 

ldelem.r8 

0x9A 

ldelem.ref 

0x9B 

stelem.i 

0x9C 

stelem.i1 

0x9D 

stelem.i2 

0x9E 

stelem.i4 

0x9F 

stelem.i8 

0xA0 

stelem.r4 

0xA1 

stelem.r8 

0xA2 

stelem.ref 

0xA3 

ldelem 

0xA4 

stelem 

0xA5 

unbox.any 

0xB3 

conv.ovf.i1 

0xB4 

conv.ovf.u1 

0xB5 

conv.ovf.i2 

0xB6 

conv.ovf.u2 

0xB7 

conv.ovf.i4 

0xB8 

conv.ovf.u4 

0xB9 

conv.ovf.i8 

0xBA 

conv.ovf.u8 

0xC2 

refanyval 

0xC3 

ckfinite 

0xC6 

mkrefany 

0xD0 

ldtoken 

0xD1 

conv.u2 

0xD2 

conv.u1 

0xD3 

conv.i 

0xD4 

conv.ovf.i 

0xD5 

conv.ovf.u 

0xD6 

add.ovf 

0xD7 

add.ovf.un 

0xD8 

mul.ovf 

0xD9 

mul.ovf.un 

0xDA 

sub.ovf 

0xDB 

sub.ovf.un 

0xDC 

endfinally 

0xDD 

leave 

0xDE 

leave.s 

0xDF 

stind.i 

background image

296 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

オプコード 

命令 

0xE0 

conv.u 

0xFE 0x00 

arglist 

0xFE0x01 

ceq 

0xFE 0x02 

cgt 

0xFE 0x03 

cgt.un 

0xFE 0x04 

clt 

0xFE 0x05 

clt.un 

0xFE 0x06 

ldftn 

0xFE 0x07 

ldvirtftn 

0xFE 0x09 

ldarg 

0xEF 0x0A 

ldarga 

0xFE 0x0B 

starg 

0xFE 0x0C 

ldloc 

0xFE 0x0D 

ldloca 

0xFE 0x0E 

stloc 

0xFE 0x0F 

localloc 

0xFE 0x11 

endfilter 

0xFE 0x12 

unaligned. 

0xFE 0x13 

volatile. 

0xFE 0x14 

tail. 

0xFE 0x15 

initobj 

0xFE 0x17 

cpblk 

0xFE 0x18 

initblk 

0xFE 0x1A 

rethrow 

0xFE 0x1C 

sizeof 

0xFE 0x1D 

refanytype 

background image

297 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

1.3 

スタック推移図 

スタック推移図は,命令の実行前及び実行後の評価スタックの状態を示す。次に典型的なスタック推移

図を示す。 

…,≪値1≫,≪値2≫◊…,≪結果≫ 

この図は,スタック上に少なくとも二つの要素がなければならないことを示す。また,この定義では,

最も上側に位置する値(“スタックの最上部”又は“最も最近スタックに入れられた要素”。)を≪値2≫と

呼び,そのすぐ下に位置する値(値2の前にスタックに入れられた値。)を≪値1≫と呼んでいる(このよ

うな推移図では,スタックは紙面を横切って右向きに成長していく。)。この命令は,スタックからこれら

の値を取り除き,この定義の中で≪結果≫と呼ばれている別の値で置き換える。 

1.4 

日本語による命令の定義 

日本語による命令の定義では,その命令について,形式及びスタック推移を示すだけでは明確にならな

い詳細な事項を定義する。 

1.5 

演算対象の型の表 

CILの演算の多くは,スタック上の数値の演算対象をとる。これらの演算は,演算対象の型をどのよう

に扱うかに応じて,幾つかの種類に分けられる。次の表は,演算対象の型の正当な種類及び結果の型につ

いて要約したものである。ここで言及した型はCLIによって追跡できるものであり,CIL正当性検証のよ

うなツールによって使われる,より詳細化された型のことではないことに注意する。CLIによって追跡さ

れる型は,int32,int64,native int,F,O及び&とする。 

表2 2項数値演算の表は,A op B形式の命令の結果の型を示す。ここでopはadd,div,mul,rem

及びsubとする。下の表は,考えられる演算対象の型の各々の組合せについて,結果の型を示す。単に結

果の型だけが書かれている欄については,五つの命令すべてに適用される。

印のついている欄は不当な

CIL命令を示す。網をかけられた欄は,正当性検証可能でないCIL命令を示す。命令の一覧が付加されて

いる欄は,その一覧にある命令にだけ有効であることを示す。 

表2−2項数値演算 

Aの型 

Bの型 

int32 

int64 

native int 

int32 

int32 

native int 

& (add) 

int64 

int64 

native int 

native int 

native int 

& (add) 

& (add, sub) 

& (add, sub) 

native int (sub) 

表3 単項数値演算の表は,単項数値演算の結果の型を示す。この表は,neg命令に使用する。

印の

ついている欄は不当なCIL命令を示す。この命令の正当な使用方法はすべて正当性検証可能とする。 

表3−単項数値演算 

演算対象の型 

int32 

int64 

native int F 

結果の型 

int32 

int64 

native int F 

background image

298 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

表4 2項比較及び分岐操作の表は,比較及び分岐命令の結果の型を示す。2進比較命令はBoolean型の

値を返し,分岐命令はスタックの最上部の二つの値に基づいて分岐を行う。この表は,beq,beq.s,bge,

bge.s,bge.un,bge.un.s,bgt,bgt.s,bgt.un,bgt.un.s,ble,ble.s,ble.un,ble.un.s,

blt,blt.s,blt.un,blt.un.s,bne.un,bne.un.s,ceq,cgt,cgt.un,clt,clt.unに使用

する。

印でマークされた欄は,命令がすべて演算対象型のその組合せに有効であることを示す。

印の

ついている欄は不当なCIL列を示す。網をかけられた欄は,正当性検証可能でないCIL命令を示す。命令

の一覧が付加されている欄は,一覧にある命令だけに有効とする。 

表4−2項比較及び分岐操作 

int32 

int64 

native int 

int32 

int64 

native int 

Beq[.s],
bne.un[.s],ceq 

beq[.s],bne.un[.s],
ceq 

 a) 

beq[.s],bne.un[.s],
ceq b) 

注a) beq,bne.un,beq.s,beq.un.s及びceqを除いて,これらの組合せは,両方の演算対象が同じ配列の

要素へのポインタであると分かっている場合に意味をもつ。しかし,CLIがこの制約を検査しないことは,
セキュリティ上の問題を生じない。 
注記 二つの演算対象が同じ配列の中へのポインタでない場合,結果は単に二つの無関係なデータ項目のご

み集め子が管理するヒープの中での距離になる。この距離は,ほぼ間違いなく,次のごみ集めが行わ
れた時点で変化してしまうだろう。本質的に,この結果は何らかの有用な計算に使うことはできない。 

b) cgt.unは許可され,ObjectRefs(O)上で正当性検証可能とする。これは,ObjectRefとnullとを比較す

る場合に一般的に使われる(より明白な解決法になるであろう,等しくないことを比較する命令はない。)。 

表5 整数演算の表は,整数演算において,オペランドがとりうる型の組合せとその演算結果の型を示

す。この表は,and,div.un,not,or,rem.un,xorに使われる。div.un及びrem.un命令は,演

算対象を符号なし整数として扱って,符号なしの結果に対応するビットパターンを作成する。しかし,CLI

規格で定義しているように,CLIは,スタック上では符号付きと符号なし整数を区別しない。not命令は

単項演算で,入力と同じ型を返す。shl及びshr命令は第1演算対象と同じ型を返し,第2演算対象は

int32又はnative int型でなければならない。

印のついている欄は不当なCIL列を示す。他のすべ

ての欄は,演算対象の正当性検証可能な組合せを表す。 

表5−整数演算 

int32 

int64 

native int 

int32 

int32 

native int 

int64 

int64 

native int 

native int 

native int 

background image

299 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

表6 シフト演算の表は,シフト命令shl,shr,shr.unの演算対象の妥当な組合せ及び結果を示す。

印のついている欄は不当なCIL列を示す。それ以外のすべての欄は,演算対象の正当性検証可能な組合

せを表す。“シフト量を指示する”演算対象が“シフトされる”演算対象の幅より大きい場合,結果は未定

義とする(例えば,int32型の整数を左に37ビットシフトした場合。)。 

表6−シフト演算 

シフト量を指示する演算対象 

int32 

int64 

native int 

シフトされる
演算対象 

int32 

int32 

int32 

int64 

int64 

int64 

native int 

native int 

native int 

表7 オーバフロー算術演算の表は,オーバフロー検査を伴う算術演算において,オペランドがとりう

る型の組合せとその演算結果の型を示す。結果が結果の型の範囲内で表現できない場合,例外が送出され

る。この表はadd.ovf,add.ovf.un,mul.ovf,mul.ovf.un,sub.ovf及びsub.ovf.unに使わ

れる。送出される例外の詳細については,各命令の箇条を参照する。網掛けされた使い方は正当性検証可

能ではない。さらに,

印のついている欄は不当なCIL列を示している。 

表7−オーバフロー算術演算 

int32 

int64 

native int 

int32 

int32 

native int 

& add.ovf.un 

int64 

int64 

native int 

native int 

native int 

& add.ovf.un 

& add.ovf.un, 
sub.ovf.un 

& add.ovf.un, 
sub.ovf.un 

native int 
sub.ovf.un 

表8 変換演算の表は,変換演算の結果の型を示す。変換演算は,評価スタック上の一番上の項目をあ

る数値型から別の数値型に変換する。表に示したとおり,変換の過程で切捨て又は拡張を行う。結果の型

は,命令の一部として指定されたデータ型として表現可能になっていることが保障される(すなわち

conv.u2命令は,unsigned int16型に格納できる値を返す。)。しかし,スタックは,最低で4バイト

の大きさの値を格納することだけができる。conv.<to type>,conv.ovf.<to type>及び

conv.ovf.<to type>.un命令に使用される。網掛けされた使い方は正当性検証可能ではない。さらに,

印のついている欄は不当なCIL列を示している。 

background image

300 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

表8−変換演算 

変換後の型 

入力(評価スタックから) 

int32 

int64 

native int 

int8 
unsigned int8 
int16 
unsigned int16 

切捨てa) 

切捨てa) 

切捨てa) 

ゼロ方向へ
の切捨てb) 

int32 
unsigned int32 

Nop 

切捨てa) 

切捨てa) 

ゼロ方向へ
の切捨てb) 

int64 

符号拡張 

Nop 

符号拡張 

ゼロ方向へ
の切捨てb) 

GC追跡を停止d) 

GC追跡を停止d) 

unsinged int64 

ゼロ拡張 

Nop 

ゼロ拡張 

ゼロ方向へ
の切捨てb) 

GC追跡を停止d) 

GC追跡を停止d) 

native int 

符号拡張 

切捨てa) 

Nop 

ゼロ方向へ
の切捨てb) 

GC追跡を停止d) 

GC追跡を停止d) 

native unsigned int 

ゼロ拡張 

切捨てa) 

Nop 

ゼロ方向へ
の切捨てb) 

GC追跡を停止d) 

GC追跡を停止d) 

すべての浮動小数
点数型 

浮動小数点
数に変換 

浮動小数点
数に変換 

浮動小数点
数に変換 

精度を変更

c) 

注a) “切捨て”は,数値を要求された大きさに切り捨てることを意味する。すなわち単純に入力の最上位バイト

側を無視する。結果が最小のスタック幅である4バイトより小さい場合,切捨てを行った結果は,ゼロ拡張
(結果の型が符号なしである場合。)又は符号拡張(結果の型が符号付きである場合。)された値になる。し
たがって,値0x1234 ABCDを評価スタックから8ビットのデータに変換すると,結果は0xCDとなる。結果
の型がint8だった場合,この結果は符号拡張されて0xFFFF FFCDとなる。また,結果の型が符号なしint8
だった場合,この結果はゼロ拡張されて0x0000 00CDとなる。 

b) “ゼロ方向への切捨て”は,浮動小数点数がゼロ方向に切り捨てられることによって整数に変換されること

を意味する。したがって,1.1は1に変換され,-1.1は-1に変換される。 

c) 評価スタック上で使用可能な現在の精度から命令によって指定された精度に変換する。スタックが出力の大

きさより高い精度をもっている場合,変換は,変換結果の低位側のビットを計算するためにIEC 60559:1989
の“最近値への丸め”(round-to-nearest)モードを用いて実行される。 

d) “GC追跡を停止”は,変換が行われた後は,その項目の値は後続のごみ集め操作には報告されないことを意

味する(したがって,その項目の値はごみ集め操作によって更新されなくなる。)。 

整数からFへの変換及びFから整数への変換に対する丸めモードは,算術演算の場合と同様とする。 

1.6 

暗黙の実引数強制型変換 

CLIは六つの型(int32,native int,int64,F,O及び&。)だけで作動しているが,メタデータは

メソッドの仮引数に,より豊富なモデルを提供する。メソッドを呼び出す直前に,CLIは次の表のように

暗黙の型変換を実行する(概念的には,CILの流れの中に適切なconv.* 命令を挿入する。conv.* 命令

の挿入は,切捨て又は丸め処理による情報の損失を生じさせる可能性がある。)。この暗黙の型変換は

を付けた欄で生じる。網掛けをした欄は正当性検証可能ではない。

印を付けた欄は不当なCIL列を示す

(当然コンパイラは,期待する効果を得るためにconv.*又はconv.*.ovf命令を明示的に生成してもよ

い。)。 

background image

301 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

表9−識別情報の一致 

識別情報中の型 

スタック仮引数 

int32 

native int 

int64 

int8 

Unsigned int8,bool 

int16 

Unsigned int16,char 

int32 

Unsigned int32 

int64 

Unsigned int64 

native int 

 符号拡張 

Native unsigned int 

 ゼロ拡張 

 ゼロ拡張 

float32 

d) 

float64 

d) 

クラス 

値型 b) 

a) 

a) 

a) 

a) 

By-Ref(&) 

 GC追跡開始 

By-Any c) 

注a) 値型であることを要求される仮引数に組込み型を渡すことは許されない。 

b) CLIのスタックは値型を保持することができる。スタック上の特定の値型が対応する仮引数によって要求さ

れるクラスを正確に一致する場合,これらの値を渡すだけでよい。 

c) Ref Anyを構築し,渡すための特別な命令がある。 

d) CLIは,その内部F型を使用することで,浮動小数点実引数を渡すことができる(1.1.1参照)。CIL生成器は

当然,明示的にconv.r4,conv.r4.ovf又は同様の命令を含めてもよい。 

この表に関するその他の備考 

− 32ビットの計算機においては,native int引数からunsigned int32に渡す場合,変換は行われない。64

ビットの計算機においては,暗黙の型変換が行われる。 

− “GC追跡開始”は,暗黙の型変換を行った後は,項目の値は任意の後続するごみ集め操作に報告され,指され

ている項目がヒープの中で再配置されるように変更される可能性がある。 

1.7 

CILコード列の制限 

CILコード列に対する詳細な制限と同様に,次の項目を保証するために幾つかの細かい制限事項が存在

する。 

− 妥当なCIL 

− 正当性検証可能なCIL 

これらの制限事項は,CILからプラットフォーム固有のコードを生成する単純なコンパイラの作成を容

易にするために設定されたものである。1.7では,個々の命令の箇所に載せている制限以外の一般的な制限

を記載する。 

1.7.1 

命令ストリーム 

メソッドの実装は,次に述べるように符号化されたCIL命令の連続したブロックによって与えられる。

一つのメソッドに対する命令ブロックのアドレスは,その長さと同様に,そのファイル形式の中で指定さ

れる(第2章,CILの物理的配置参照)。一つ目の命令は,命令ブロックの第1バイトの位置(最も低位

のアドレス。)に配置される。 

命令語長は可変とする。各命令の語長は,命令バイト列自身の内容から決定(復元)することができる。

302 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

命令語長及び命令中のバイト列の並び順は,各命令の定義で述べる。命令は,バイト列のストリーム中で,

境界調整及びバイト順序表現に関係なく,詰め物なしで互いに連続して配置される。 

各命令はちょうどよいバイト数分の領域を占有する。また,命令ブロックの終了位置に達するまで,次

の命令は前の命令の直後のバイト位置から始まる(ブロック長によって長さが指定されている。)。命令ブ

ロックが最後の命令を完全な状態にしないまま終了することは不当とする。 

命令接頭辞は,新しい命令を導入せずに命令の長さを拡張する。一つ以上の接頭辞をもつ命令は,最初

の命令接頭辞の最初のバイトから始まる命令を一つだけ導入する。 

注記 命令ブロックの終了位置まで,任意の制御移行命令に後続する命令は,命令として復号され,

その命令が分岐先ではない場合でも,後続する命令に加えられる。到達不能な場合でも,命令

ストリーム中に命令が現れてもかまわない。アドレス相対データアドレッシングモードはなく,

生データを直接命令ストリーム中に埋め込むことはできない。幾つかの命令は,命令の一部と

して即値データを埋め込むことを許可する。しかし,それは命令ストリームに生データを直接

埋め込むことを許可することとは異なる。機械がコード生成を行った結果,到達不能コードが

現れる可能性があり,それは許容されるが,生成されたコードは常に適切な命令列を形成して

いなければならない。 

命令ストリームは,変換することができ,変換の実行に先立って関連する命令ブロックを破

棄することができる。したがって,call,retなどのようなコードアドレスの取得及び操作を

行う命令であっても,CIL命令ストリーム中のアドレスの代わりに変換されたアドレスを操作

するために仮想化できる。 

1.7.2 

妥当な分岐対象 

命令ストリームの中で識別された各命令の最初のバイトで構成したアドレス集合は,唯一の妥当な命令

対象を定義する。命令対象は,分岐命令で指定された分岐対象,保護範囲(第1章及び第2章参照)のよ

うな例外表で指定された対象,フィルタ及びハンドラ対象を含む。 

分岐命令は,1バイト又は4バイトの符号付き相対オフセットとして分岐対象を指定する。オフセット

の大きさは命令のオプコードによって区別する。オフセットは,分岐命令の直後のバイトからの相対値と

して定義される。 

注記 したがって,オフセット値ゼロは直後の命令を指す。 

1バイトのオフセット値は,そのバイトを符号付き8ビット整数と解釈して算出する。4バイトのオフセ

ット値は,そのバイト列を符号付き整数として連結することによって計算できる。この場合,最も低位の

アドレスのバイトを最下位バイトとし,最も高位のアドレスを保持しているバイトを,整数の最上位バイ

トとする。 

注記 この形式は,しばしば“リトルエンディアンバイト順序の符号付き整数”と呼ばれている。 

1.7.3 

例外区間 

例外表は,catch,fault及びfinallyハンドラ(第1章及び第2章参照)によって保護される命令

の範囲を記述する。限定公開ブロック,filter節又はハンドラの開始アドレスは,1.7.2で定義する妥当

な分岐対象でなければならない。限定公開ブロック,filter節又はハンドラが完全な最後の命令を形成

しないまま終了することは不当とする。 

1.7.4 

maxstackを提供しなければならない 

すべてのメソッドは,CIL評価スタックに投入することができる項目数の最大値を指定する。その値は,

各メソッドのCIL本体の前におかれているIMAGE̲COR̲ILMETHOD構造体に格納する。メソッドを静的に

303 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

(データの分析を行わずに伝統的な制御フローグラフを使って)分析することによって必要と分かる数よ

り小さい項目数の最大値を指定するメソッドは不当(したがって正当性検証不能)であり,CLI規格適合

処理系はこのようなメソッドに対応する必要はない。 

注記1 maxstackは,実行時のスタックの大きさではなく,プログラムの分析と関連する。maxstack

は,スタックフレームの最大バイト数を指定するのではなく,解析ツールによって追跡され

る項目の個数を指定する。 

注記2 (根拠)任意のメソッドのCILストリームを分析することによって,CIL評価スタックに投

入されるであろう項目数を容易に知ることができる。しかし,あらかじめ最大値を指定して

おくことで,CILをプラットフォーム固有のコードに変換するコンパイラ(特にCILストリ

ームを1パスで変換する単純なコンパイラ。)がスタックを実現する内部データ構造の割付け

及び/又は検証アルゴリズムに有益である。 

1.7.5 

後方分岐制約 

任意のメソッドについて,CIL命令ストリームを前方に1回走査することで,各々の命令を処理する時

点での評価スタックの正確な状態を推論することが可能でなければならない(ここで“状態”とは,評価

スタック上の各項目の個数及び型を意味する)。 

特に,1回走査の解析が,無条件分岐の直後のある命令に到達し(ここを位置Xと呼ぶ),Xがそれまで

に出現したどの分岐命令の対象でもない場合,Xにおける評価スタックの状態は明らかに,その時点の情

報からは導出できない。この場合,CLIでは,Xにおける評価スタックは空でなければならない。 

この規則から,後に出現するXへの分岐命令が,空でない評価スタックをもっている場合,不当なCIL

とする。 

注記 (根拠)この制約は,CILをプラットフォーム固有のコードに変換する単純なコンパイラがCIL

コードを処理できることを保証する。この制約は,1回の前方走査解析で,各CILの開始時点

の評価スタックの状態が推論できることを保証する。 

注記 先述した場所Xにおけるスタック状態は,Xが前方分岐から参照されているとか,Xが例外ハ

ンドラの開始位置になっているなど,様々な方法で推論可能になる。 

より詳細な情報については,次の章節を参照。 

− 例外 第1章 

− 分岐命令の検証条件 箇条3 

− tail.接頭辞 3.19 

1.7.6 

分岐検証制約 

すべての分岐命令の対象は,その分岐命令を含んでいるメソッドの内で妥当な分岐対象でなければなら

ない(1.7.2参照)。 

1.8 

正当性検証可能性及び適正性 

メモリ安全性とは,同じアドレス空間中で動作しているプログラムを互いに適切に分離することを保証

する性質の(第1章参照)。したがって,プログラムを動作させる前に,そのプログラムがメモリ安全か

どうかを検査することが望ましい。しかし,メモリ安全なプログラムかどうかを100 %正確に検査するこ

とは不可能であることが分かっている。その代わり,CLIは,正当性検証可能性と呼ばれる,より強い制

限についての検査を行うことができる。正当性検証されたすべてのプログラムはメモリ安全とする。しか

し,正当性検証可能でないプログラムであっても,メモリ安全になっていることがある。 

適正なCILとは,この規格で規定したとおりに動作する,すべてのCLI規格適合処理系で実行可能な

304 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

CILのこととする。しかし,適正なCILは規格適合処理系をまたいで同じ動作になる必要はない。すなわ

ち動作は実装に依存するかもしれない。 

正当性検証可能でないが,コンパイラ作成者によってメモリ安全であることが確かめられている適正な

CILコードを生成することは完全に受容できる。したがって,たとえ,コンパイラがそのCILコードがメ

モリ安全であると分かっていたとしても,適正なCILは正当性検証可能ではないかもしれない。CIL命令

の重要な使用法の幾つかは正当性検証可能ではない。このような命令には,C言語プログラムをコンパイ

ルする場合に必要になる,C言語の動作に忠実で効率よく動作するaddのポインタ演算版のようなものが

ある。正当性検証不能なコードについては,メモリ安全性の確保は,アプリケーションプログラマの責任

とする。 

CILは正当性検証可能な部分集合を含む。正当性検証可能性記述は,命令の使用法がCILの正当性検証

可能な部分集合の範囲内に入る条件についての詳細を示す。CLIの基本的な機能を提供するために,より

詳細な値の型を追跡する正当性検証が必要となる。これは,正当性検証が,CILコード列がごみ集めの安

全性に関するCLIの基本的な規則だけでなく,CTSの型使用についての規則も遵守しているということを

検査することによる。これは,CLI全体の健全な動作を保障することを支援する。 

各々の操作記述の正当性検証可能性節は,適正なCIL生成及び正当性検証の両方の要件を指定する。適

正なCILの生成は,スタック推移図中に示された型にスタックの最上部の項目が一致することを保証する

ことを常に要求する。正当性検証可能性節は,その推移図の中で取り込まれない適正なCIL生成の要件だ

けを指定する。正当性検証は,適正なCIL生成の要件及び命令とともに記述される特定の正当性検証の検

査条件の両方を試験する。適正なCILとしての要件を満たさないCIL列の動作は未規定とする。適正な

CILとしての要件を満たしているが,正当性検証可能ではないCILの動作は,型安全性を害し,そのため,

セキュリティ又はメモリアクセスの制約を害するかもしれない。 

追加の情報については,第2章の箇条3を参照する。 

1.8.1 

正当性検証可能なCILのためのフロー制御の制限 

この箇条は正当性検証アルゴリズムを規定する。正当性検証アルゴリズムは,個々のCIL命令に付加さ

れている情報(箇条3参照)及びメタデータ妥当性検証(第2章参照)とともに,メモリ整合性を保証す

る。 

ここで規定するアルゴリズムは,このアルゴリズムによって正当性検証可能であると判断されたプログ

ラムはすべて,正当性検証可能であるとみなされ,CLIに合致した任意の実装において正しく実行される

という観点で,この規格に合致したすべての実装に対する最低のレベルを規定する。 

CLIは,CLIがメモリの安全性を害する可能性のあるプログラムを実行しなければならないかどうかを

制御するセキュリティアクセス許可(第4章参照)を提供する。この規格に照らして正当性検証可能なプ

ログラムはすべて,メモリの安全性を害さない。また,CLIの規格適合処理系は,そのようなプログラム

を実行できなければならない。規格適合処理系は,正当性検証可能なプログラム以外に,メモリの安全性

を害さないことを知りうるプログラムについても実行可能であってもよい(これは,典型的には,それら

が実装に関する特定の知識を利用する正当性検証アルゴリズムを使用することによる)。 

注記 規格適合処理系は,この正当性検証アルゴリズムが正当性検証可能であると判定する任意のプ

ログラムを受け入れて実行する必要がある。しかし,ある特定の処理系には正当性検証可能で

あるとして受け入れられるが,この正当性検証アルゴリズムでは正当性検証可能であるとはみ

なされないプログラムが存在するかもしれない。そのようなプログラムは,その特定の処理系

では実行されるだろうが,他の処理系がそのプログラムを妥当性検証可能であるとみなす必要

305 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

はない。 

例えば,ここで規定した正当性検証アルゴリズムが許可しないにもかかわらず,あるCLI処

理系が,メソッドポインタについて正しく完全な識別情報の追跡を行い,calli命令を実行す

るかもしれない。 

CLIの実装者は,彼らの処理系が生成したプログラムが,このはん用性のある正当性検証可

能性規約を満足するものであるかどうかを試験する手段を提供しなければならない。また,実

装者は,彼らの正当性検証アルゴリズムがこの規約よりも寛容な部分について規定しなければ

ならない。 

妥当なプログラムだけが正当性検証可能とする。説明を容易にするため,ここで定義する正当性検証ア

ルゴリズムは,プログラムが妥当であり,妥当性についてのすべての条件を明示的に試験する必要がない

ものと仮定する。妥当性についての条件は,各CIL命令語の基本事項(箇条3)及び第2章の全体的なフ

ァイル形式で規定する。 

1.8.1.1 

正当性検証アルゴリズム 

正当性検証アルゴリズムは,すべてのCIL命令に妥当なスタック状態を関連付けることを試みなければ

ならない。スタック状態は,コード中のその地点におけるCILスタック上のスロットの個数を規定し,各々

のスロットについて,そのスロットの中で存在しなければならない要求される型を規定する。スタックの

初期状態は空とする(スタック上に項目はない)。 

正当性検証は,メモリがプログラムから可視の状態になる前に,CLIが評価スタックを除くすべてのメ

モリをゼロにすることを仮定する。CLIの規格適合処理系は,この観測可能な動作を提供しなければなら

ない。さらに,正当性検証可能なメソッドは,localsinitビットを設定する(メソッドヘッダのフラグ,第

2章参照)。このビットが設定されていない場合,CLIは,SecurityPermission.SkipVerificationが指定されて

いないメソッドを含むアセンブリの,局所変数がアクセスされた任意の地点において,Verification例外を

送出するかもしれない。 

注記1 (根拠)この要件はプログラムの可搬性を大きく高める。よく知られた技術(有限代入分析)

は,CILをプラットフォーム固有のコードに変換するコンパイラが,その性能への影響を最

小化することを可能にする。CLIが有限代入分析を行うことを選択してもよいことに注意す

る。そのような場合,localsinitビットが設定されていないもの,実際には正当性検証可能な

もの,したがってVerification例外を送出しないものについても,メソッドを確認してもよい。 

注記2 CLIは,読み込む前にどの位置が書込みされたかを決めるために有限代入分析を使うことが

できる。VESが提供した状態のままのメモリの内容を観測することはできないため,それら

の位置はゼロである必要はない。 

C++処理系の性能測定(それらは有限代入分析を要求しない。)は,高度に最適化されたコ

ードにおいてさえ,この要件が性能に影響を与えないことを示している。さらに,このゼロ

初期化が行われない場合,利用者はこれをコンパイラのバグだと誤解するかもしれない。こ

れは,プログラムに小さくて無関係な変更を加えた場合に,そのようなコードがしばしば失

敗することによる。 

正当性検証アルゴリズムは,コード全体を通して,考えられるすべての制御フロー経路を模擬し,すべ

ての到達可能なCIL命令に対して妥当なスタック状態になっていることを保証しなければならない。正当

性検証アルゴリズムは,模擬実行中はデータの値を全く利用せず(例えば,定数伝ぱも行わない。),型の

代入だけを使用する。正当性検証に使われる型システム及びスタック状態を結合するために使われるアル

306 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

ゴリズムは,1.8.1.3で規定する。正当性検証アルゴリズムの終了状態は,次のとおりとする。 

1) 制御パスがすべて模擬された場合,成功とする。 

2) 特定のCIL命令についての妥当なスタック状態を計算することができない場合,不成功とする。 

3) この箇条の中で規定する追加の試験が失敗する場合,不成功とする。 

無条件分岐命令であるthrow,rethrow及びretの例外について,すべての命令から後続の命令への

制御フロー経路がある。(条件付き又は無条件の)各分岐命令から分岐対象(switch命令に対しては複数

の分岐対象。)までの制御フロー経路がある。 

正当性検証は,新しいスタック状態を求めるために,各CIL命令の操作を模擬する。スタック状態につ

いての指定されている条件(箇条3参照)と模擬されたスタック状態との間に生じたいかなる不一致も,

正当性検証アルゴリズムを失敗させなければならない(正当性検証がスタック状態に対する影響だけを模

擬することに注意する。正当性検証では実際の計算は実行しない。)。次の命令アドレス(条件分岐及びtry

ブロック内の命令については,複数の命令アドレスになり得る。)における実際のスタック状態が,求めら

れたスタック状態と結合できない場合,正当性検証アルゴリズムは失敗する。この結合操作の規則につい

ては,1.8.1.3を参照する。 

CLIは制御された変更可能な 管理下ポインタの概念を提供する(1.8.1.2.2,1.8.1.3のマージについての

規則,2.3のreadonly命令接頭辞,4.10のldfld命令,4.30のstfld命令及び4.32のunbox命令を

参照。)。 

VESは特殊制約及び型制約の両方が満たされていることを保証する。制約の検査については,早い場合

には閉型を構築する時点で検査される可能性がある。また,遅い場合には,制約付き総称型のメソッドが

呼び出される時点,制約付き総称メソッドを呼び出す時点,制約付き総称型の中のフィールドをアクセス

する時点又はインスタンスを生成する時点まで検査しない可能性もある。 

総称型に対応するため,次の二つの項目を扱えるように型互換性関係を拡張する。 

− 総称仮引数:任意の総称仮引数はその総称仮引数とだけ互換性をもつこととする。 

− ボックス化された総称仮引数:ボックス化された総称仮引数は総称仮引数上で宣言された制約型と互

換性をもつこととする。 

正当性検証の意味においては,スタック上の原始的な型,すなわち値型 をボックス化することは,ボッ

クス化された型の値を導入することになる。すなわち,その値型がNullable<T>(第1章,8.2.4参照)だ

った場合,Tをボックス化した型の値が導入される。ボックス化された型についてのこの考え方を,総称

仮引数に拡張する。型が総称仮引数(例えば!0)で指定されている値をボックス化することは,スタック

上にボックス化された仮引数型(例えばボックス化された!0)の値を導入する。値型をボックス化した形

式,すなわち拡張後の考え方における総称仮引数をボックス化した形式は,効率的なインスタンス呼出し

及びボックス化された値の仮想メソッドの効率的な呼出しを提供するために使われる。ボックス化された

型はボックス化前の値の正確な型を静的に記録しているため,そのインスタンスについて,より情報が少

ないが文法的に記述可能な参照型からの検査文脈での変換を実行する必要がない。 

原始的な値型及び原始的ではない値型をボックス化した形式と同じように,総称仮引数をボックス化し

た形式は,正当性検証スタック上にしか現れない(box命令によって導入されたあとにしか現れない)。メ

タデータ識別情報を使って総称仮引数をボックス化した形式を明示的に指定することはできない。 

1.8.1.2 

正当性検証型システム 

正当性検証アルゴリズムは,型を圧縮することがメモリ安全性を害することに結びつかないため,論理

的に等価な型を圧縮する。正当性検証アルゴリズムが使用する型は,1.8.1.2.1で規定する。型の互換性に

background image

307 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

ついての規則は1.8.1.2.2で規定する。また,スタック状態を結合するための規則は1.8.1.3で規定する。 

1.8.1.2.1 

正当性検証型 

次の表は,CLIの中で使用される型及び正当性検証で使用される型の対応付けを規定する。正当性検証

がCLIの型を,メモリ中でのそれらの型の大きさについての情報を維持する,より小さな集合に圧縮する

が,しかし,更に,CLIスタックが1,2及び4バイトの組込み型をスタック上で4バイトの型に展開する

という事実を表現するため,再度これらの圧縮が行われることに注意する。同様に,正当性検証は,実際

の表現とは無関係に,スタック上では浮動小数点数を64ビットの量として取り扱う。 

配列はオブジェクトとするが,特殊な互換性規則をもつ。 

あるオブジェクトが無効な値であることを表現するnullに対しては特殊な符号が存在し,実際の型は

不定とする。 

次の表では,“CLI型”の欄はメタデータで記述される型である。“正当性検証の型”の欄は,正当性検

証において,呼び出されるメソッドの局所変数,実引数及び仮引数の型を考慮する場合,型の互換性規則

として使われる対応する型とする(1.8.1.2.2参照)。“正当性検証の型(スタック状態における)”の欄は,

データをスタックにロードする命令を模擬するために使われ,正当性検証アルゴリズムのスタック状態情

報の中で実際に保持される型を示す。“型への管理下ポインタ”の欄は,管理下ポインタのために追跡され

る型を示す。 

CLI型 

正当性検証の型 

正当性検証の型 

(スタック状態における) 

型への管理下ポインタ 

int8, unsigned int8, bool 

int8 

int32 

& int8 

int16, unsigned int16, char 

int16 

int32 

& int16 

int32, unsigned int32 

int32 

int32 

& int32 

int64, unsigned int64 

int64 

int64 

& int64 

native int, native unsigned int native int 

native int 

& native int 

float32 

float32 

float64 

& float32 

float64 

float64 

float64 

& float64 

任意の値型 

同じ型 

同じ型 

& 同じ型 

任意のオブジェクト型 

同じ型 

同じ型 

& 同じ型 

メソッドポインタ 

同じ型 

同じ型 

妥当ではない 

メソッドが管理下ポインタを返すように定義することができる。しかし,そのようなメソッドの呼出し

は正当性検証可能ではない。byrefで返却する場合,正当性検証は呼出し元ではなく返却する側で行われる。 

注記 (根拠)管理下ポインタを返すメソッドを用いていても,完全に正当性検証可能な場合もある

(例えば,オブジェクト中のフィールドへの参照を返す場合。)。しかし,正当性検証可能でな

い場合もある(例えば,呼び出されたメソッドの局所変数へのポインタを返す場合。)。一般の

場合について,これを追跡することは,負荷が高い。したがって,この規格には採用しないこ

ととした。 

1.8.1.2.2 

制御された変更可能な管理下ポインタ 

readonly接頭辞及びunbox命令を使うことで,制御された変更可能な管理下ポインタと呼ばれる管

理下ポインタを生成することができる。通常の管理下ポインタ型と異なり,制御された変更可能な管理下

ポインタは,通常の管理下ポインタとの互換性がない。例えば,制御された変更可能な管理下ポインタは,

byref実引数としてメソッドに渡すことができない。制御フローの観点では,制御された変更可能な管理下

ポインタは,制御された変更可能な管理下ポインタを生成するための型と同じ型の管理下ポインタと結合

できる。 

308 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

制御された変更可能な管理下ポインタは,次の方法だけで使用できる。 

1) ldfld,ldflda,stfld,call,callvirt又はconstrained. callvirt命令に対するオブジェクト仮引数 として使

用する。 

2) ldind.*又はldobj命令のポインタ仮引数として使用する。 

3) cpobj命令のコピー元仮引数として使用する。 

stobj,stind.*,initobj及びmkrefanyも含め,その他の操作はいずれも不当とする。 

定義する型がその値が変更可能かどうか決めるため,このポインタは制御された変更可能な管理下ポイ

ンタと呼ばれる。フィールド及び値を正しく更新するメソッドをまったく公開しない値クラスについては,

このポインタは読込み専用とする(その接頭辞の名前にしたがい)。特に,System.Int32のような原始

的な型を表すクラス群は変更子を公開しないから,読込み専用とする。 

1.8.1.2.3 

正当性検証の型互換性 

次の規則は型の互換性を定義する。正当性検証の型を表記するために,S及びTを用いる。“S:=T”とい

う表記は,正当性検証の型Sが使用できるところならどこでも正当性検証の型Tが使用できることを示す。

また,“S!:=T”は,Sが期待されている箇所でTが使用できないことを示す。これらは正当性検証の型互

換性(第1章参照)の規則とする。要素が型Tである(任意の次元数の)配列を表すためにT[]を使用す

る。また,型Tへの管理下ポインタを表すためにT&を使用する。 

1) [:=は反射的とする] すべての正当性検証の型Sに対して,S:=Sとする。 

2) [:=は推移的とする] すべての正当性検証の型S,T及びUについて,S:=T及びT:=Uならば,

S:=Uとする。 

3) SがTの基底クラス又はTによって実装されるインタフェースであり,Tが値型でない場合,S:=T

とする。 

4) Tがインタフェース型である場合,object := Tとする。 

5) S及びTがいずれもインタフェースであり,Tの実装がSの実装を要求する場合,S:=Tとする。 

6) Sがオブジェクト型又はインタフェースである場合,S:=nullとする。 

7) S[]及びT[]について,S:=Tであり,かつ配列がいずれもベクトル(添字が0から始まり,次元数

が1の配列。)であるか,又はいずれもベクトルではなく同じ次元数をもつ場合,S[]:=T[]とする。

この規則は共変配列を扱う。 

8) S及びTがメソッドポインタである場合,識別情報(返却値の型,仮引数の型及び呼出し規約)が

同じであれば,S:=Tとする。 

9) そうでなければ,S!:=Tとする。 

1.8.1.3 

スタック状態の結合 

正当性検証アルゴリズムが制御フロー経路のすべてを模擬する時に,正当性検証アルゴリズムは,フロ

ー中の次のCIL命令における任意の既存のスタック状態と模擬されたスタック状態とを結合しなければな

らない。既存のスタック状態がない場合,模擬されたスタック状態は将来の使用のために保留される。そ

うでなければ,結合が次のとおり計算されなければならず,そのCIL命令のための既存のスタック状態を

置換するために保持されなければならない。結合が失敗する場合,検証アルゴリズムは失敗しなければな

らない。 

結合は,各スタック状態のスロット数を比較することによって計算されなければならない。スロット数

が異なる場合,結合は失敗しなければならない。スロット数が一致する場合,次のとおりスロットごとに

状態を結合することによって,全体的な結合が計算されなければならない。新たに計算された状態におけ

309 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

るスロットの型をTとし,直前に保持されていた状態における対応するスロットの型をSとする。結合し

た型をUとすると,Uは次のとおり計算しなければならない(S:=Tは,1.8.1.2.2で定義した互換性につい

ての関数であることに注意する。)。 

1) S:=Tのとき,U=Sとする。 

2) そうでなければ,T:=Sのとき,U=Tとする。 

3) そうでなければ,S及びTがいずれもオブジェクト型のとき,VをS及びTの最も近い共通のスー

パータイプとすると,U=Vとなる。 

4) そうでなければ,結合は失敗しなければならない。 

制御された変更可能な管理下ポインタと同じ型への通常の管理下ポインタを結合した結果は,その型へ

の制御された変更可能な管理下ポインタとなる。 

1.8.1.4 

クラス及びオブジェクトの初期化規則 

VESは,すべての静的メンバが初期状態で0になっていることを保証する(すなわち,組込み型は0又

は偽,オブジェクト参照はnullに初期化される。)。したがって,正当性検証アルゴリズムは,静的メンバ

への有限代入に対する試験を行わない。 

新しく構築されるオブジェクトについて,基底クラスの構築子又はそのオブジェクトのクラスの別の構

築子が呼び出された場合を除き,オブジェクト構築子から制御が戻ってはならない。正当性検証アルゴリ

ズムは,基底クラスの構築子が呼び出されていない場合,thisポインタを未初期化とみなさなければな

らない。そのオブジェクトのフィールドへの格納及びそのオブジェクトのフィールドからのロードを除き,

未初期化のthisに対して実行できる操作はない。 

注記 構築子が例外を生成する場合,対応するcatchブロック中のthisポインタは,まだ未初期化

の状態とする。 

1.8.1.5 

委譲構築子 

正当性検証アルゴリズムは,委譲を構築するために,次のコード列のうちの一つを要求する。正当性検

証可能なコード中の他のいずれのコード列も,委譲型に対するnewobj命令を含んではならない。委譲(多

重定義は許可されない。)に対するインスタンス構築子メソッドは,一つだけ存在しなければならない。 

分岐対象がこれらの命令列内(コード列の最初を除く。)にある場合,正当性検証アルゴリズムは失敗し

なければならない。 

注記 委譲の識別情報並びに構築子の中で使われるメソッドの識別情報及び委譲クラスのInvokeの識

別情報,及び委譲クラスの他のメソッドの識別情報に関する妥当性要件は,第2章を参照する。 

1.8.1.5.1 

仮想ディスパッチ経由の委譲 

次のCIL命令列を使用しなければならない。そうでなければ,正当性検証アルゴリズムは失敗する。コ

ード列は,スタック上のオブジェクトから処理を始める。 

dup 

ldvirtftn mthd 

; Method shall be on the class of the object, 

          ; or one of its parent classes, or an interface 

          ; implemented by the object 

newobj delegateclass::.ctor(object, native int) 

注記 (根拠)dupは,それが委譲の中に格納されたその仮想メソッドを計算するのに使われたのと

正確に同一のオブジェクトであることを保証するために必要となる。部分型の別のオブジェク

トが使用された場合,そのオブジェクトとメソッドとは一致しない可能性があり,メモリ破壊

310 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

につながる可能性がある。 

mthdがボックス化された値型以外のインスタンスのfinalではない仮想メソッド である場合,正当性検

証は,呼び出されようとしているメソッドへのインスタンスの参照が,ldarg 0,ldarg.s 0,ldarg 0

の結果であること,及び呼出した側の本体がstarg.s 0,starg 0又はldarga.s 0,ldarga 0を含

んでいないことも検査する。 

1.8.1.5.2 

インスタンスディスパッチ経由の委譲 

次のCIL命令列を使用しなければならない。そうでなければ,正当性検証アルゴリズムは失敗する。コ

ード列は,null又はスタック上のオブジェクトのいずれかから処理を始める。 

ldftn mthd ; Method shall be a static method 

    ; or a method on the class of the object on 

    ; the stack or a method on any parent class 

    ; of the object on the stack. In addition, if 

    ; the method is virtual, the object on the stack 

    ; must be the “this” pointer of the currently 

    ; executing method (the result of a ldarg.0, 

    ; ldarg.s 0, or ldarg 0 instruction), and the 

    ; current method body must not include any 

    ; starg.s 0, starg 0, ldarga.s 0, or ldarga 0 

    ; instructions. 

newobj delegateclass::.ctor(object, native int) 

1.9 

メタデータトークン 

多くのCIL命令は,後ろに“メタデータトークン” が続く。メタデータトークンは,4バイトの値であ

り,メタデータ表の行を指定するか,又は,利用者文字列ヒープ中の開始位置のバイトオフセットを指定

する。トークンの最上位バイトは表又はヒープを指定する。例えば,値0x02はTypeDef表を指定する。値

0x70は利用者文字列ヒープを指定する。値は,メタデータ表(表の完全な一覧については第2章を参照。)

に割り当てられた数又は利用者文字列ヒープに対応する0x70と一致する。最下3バイトは,そのメタデー

タ表内の目的の行を指定するか,又は,利用者文字列ヒープ内の開始位置のバイトオフセットを指定する。

メタデータ表内の行は,1から増加する方向に付番され,ヒープ中のオフセットはゼロから増加する方向

に付番される(したがって,例えば,値0x02000007をもつメタデータトークンは,TypeDef表中の行番号

7を指定する。)。 

1.10 送出される例外 

CIL命令は様々な例外を送出することができる。CLIは,ExecutionEngineExceptionと呼ばれる多

目的の例外を送出することもできる(第1章参照)。 

命令の接頭辞 

これらの特殊な値は,特定の命令の前に付加するために予約される。接頭辞自身は完全な命令を構成し

ない。接頭辞に後続する命令への分岐は,妥当なCILではない。しかし,接頭辞自身は妥当な分岐対象と

する。接頭辞が先行することを許されている命令群のうちの一つが後続しない接頭辞をもつCILは妥当で

はない。 

2.1 

constrained. −(接頭辞)変数型の値のメンバを呼び出す 

background image

311 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

形式 

アセンブリ形式 

定義 

FE 16 <T> 

constrained. ≪この型≫ 型Tになるように制約付けされた型の仮想メソッドを呼び出す 

スタック遷移 

…, ≪ポインタ≫, ≪実引数1≫, … ≪実引数N≫ ◊ …, ≪ポインタ≫, ≪実引数1≫, … ≪実引数N

≫ 

定義 

接頭辞constrained.は,callvirt命令にだけ付加できる。≪ポインタ≫の型は≪この型≫への管理

下ポインタ(&)でなければならない。接頭辞constrained.は,≪この型≫が値型であるか参照型であ

るかに関係なく,統一的な方法でcallvirt命令を実行できるように設計されている。 

callvirt ≪メソッド≫命令にconstrained. ≪この型≫接頭辞がついていた場合,その命令は次の

ように実行される。 

− ≪この型≫が(値型と対立する型である)参照型である場合, 

≪ポインタ≫の参照を解除したのち,≪ポインタ≫をcallvirt≪メソッド≫へのこのポインタとして

渡す。 

− ≪この型≫が値型で,かつ≪この型≫が≪メソッド≫を実装している場合, 

≪ポインタ≫は,≪この型≫によって実装された≪メソッド≫の呼出しへのthisポインタとして,

修飾されることなく渡される。 

− ≪この型≫が値型で,かつ,≪この型≫が≪メソッド≫を実装していない場合, 

≪ポインタ≫の参照を解除し,≪ポインタ≫をボックス化して,callvirt≪メソッド≫へのthisポ

インタとして渡される。 

この最後の条件は,≪メソッド≫がSystem.Object, System.ValueType又はSystem.Enum上に

定義されており,かつ,≪この型≫によって上書きされていない場合にだけ成り立つ。この最後の条件が

成り立つ場合には,ボックス化によって,ボックス化の対象となっている本来のオブジェクトのコピーが

作られる。しかし,System.Object,System.ValueType及びSystem.Enum上のすべてのメソッド

はオブジェクトの状態を変更しないので,コピーが作られたことは分からない。 

constrained.接頭辞の必要性は,もともと総称性をもつコードを作るIL生成器によって動機付けさ

れていた。通常,callvirt命令は値型については妥当ではない。しかし,ILコンパイラがILをコンパ

イルする時に,≪ポインタ≫の型及び呼び出されようとしているメソッドに依存せずに,上に概要を示し

たthis変換を効率的に実行するために必要になる。しかし,≪ポインタ≫が総称型である場合には,IL

をコンパイルする時点では型が分からないので,ILをコンパイルする時点でこの変換を行うことはできな

い。これがconstrained.接頭辞が必要になった理由である。constrained.オプコードは,≪ポイン

タ≫が値型か参照型かに関係なく,ILコンパイラが仮想関数の呼出しを統一的な方法で生成できるように

する。これが≪この型≫が総称型の変数である場合を想定したものであったが,constrained.は総称型

ではない型に対してもうまく動作し,かつ値型と参照型の区別を隠ぺいする言語において,仮想呼出しを

生成する時の複雑さを緩和することができる。 

例外 

なし。 

適正性 

接頭辞constrained.の直後にはcallvirt命令が続かなければならない。≪この型≫は妥当なtypedef,

typeref又はtypespecメタデータトークンでなければならない。 

background image

312 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

正当性検証可能性 

実引数≪ポインタ≫は,≪この型≫への管理下ポインタ(&)でなければならない。さらに,上に示し

た≪ポインタ≫の変換を行ったのち,callvirt命令の通常の正当性検証規則をすべて適用する。これは,ボ

ックス化した≪この型≫が≪メソッド≫をもつクラスのサブクラスになっていることを要求することと等

価である。 

注記 (根拠)この命令の目的が仮想関数の呼出しを統一することであったため,仮想関数の呼出し

は総称ルーチン の中で正当性検証可能なように生成することができた。この統一を実現する方

法の一つとして,callvirt命令を生成する前にthisポインタを常にボックス化する方法が

考えられる。この方法は参照型(ボックス化が意味をもたない)及び値型の両方に対して有効

である。この方法の問題点は,値型である場合にコピーが作られることである。したがって,

呼び出そうとしているメソッドがこの値型の状態を変更してしまう場合,その変更はボックス

化したコピーのほうに適用されるので,呼出しが完了したあとの状態には反映されないという

ことである。この意味上の相違があるため,この代替手法は受け入れられない。また,より多

くのボックス化を行うことによる性能面での損失が生じることも,この代替手法が受け入れら

れない理由である。 

2.2 

no. −(接頭辞)可能であれば違反検査を省略する 

形式 

アセンブリ形式 

定義 

FE 19  
<unsigned int8> 

no. { typecheck 
  | rangecheck 
  | nullcheck } 

通常であれば後続する命令の実行の一部として実行される違反検査
のうち,指定したものを省略できること又は省略しなければならない
ことを示す。 

定義 

この接頭辞は後続する命令に対して実行時に指定した検査を行う必要がないことを示す。命令コードの

後ろの1バイトはどの検査が省略可能か否かを示す。この命令は正当性検証可能ではない。 

この接頭辞は次の条件下で使用できる。 

− 0x01: typecheck(castclass,unbox,ldelema,stelem,stelem) CLIは,通常であれば

後続する命令の実行の一部として実行する型検査を省略してもよい。検査が失敗した場合には,依然

としてInvalidCastExceptionが送出される可能性がある。 

− 0x02: rangecheck(ldelem.*,ldelema,stelem.*) CLIは,通常であれば後続する命令の

実行の一部として実行する値の範囲についての検査を省略してもよい。検査が失敗した場合には,依

然としてIndexOutOfRangeExceptionが送出される可能性がある。 

− 0x04: nullcheck(ldfld,stfld,callvirt,ldvirtftn,ldelem.*,stelem.*,ldelema) 

CLIは,通常であれば後続する命令の実行の一部として実行するnull参照についての検査を省略し

てもよい。検査が失敗した場合には,依然としてNullReferenceExceptionが送出される可能性

がある。 

− 命令コードの後ろの1バイトの値は,論理和をとったものとしてよい。例えば,値0x05はtypecheck

及びnullcheckの両方を省略してよいことを示す。 

例外 

なし。 

適正性 

適正なILは,上に指定した命令に対してだけこの接頭辞を付けてよい。 

background image

313 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

正当性検証可能性 

正当性検証可能なILはno.を使ってはならない。 

2.3 

readonly.(接頭辞)−後続する命令が制御された変更可能な管理下ポインタを返すことを示す 

形式 

アセンブリ形式 

定義 

FE 1E 

readonly. 

後続の配列アドレス操作が実行時に型検査を行わないこと,及び制御
された変更可能な管理下ポインタを返すことを示す。 

定義 

この接頭辞は,ldelema命令の直前にだけ指定することができ,配列を指す特別なアドレス操作メソッド

を呼び出す。この接頭辞は後続する操作に対して二重の効果をもつ。 

1) 実行時にはいかなる型検査も行われないようにする。(値クラスである場合には,実行時の型検査は

行われないため,この接頭辞は何も行わない。) 

2) 正当性検証がアドレス操作の結果を制御された変更可能な管理下ポインタとして扱うようにする

(1.8.1.2.2参照)。 

例外 

なし。 

適正性 

正当性検証可能性 

制御された変更可能な管理下ポインタは,1.8.1.2.2の2)に示した正当性検証規則に従わなければならな

い。 

注記 (根拠)readonly.接頭辞の主たる目的は,総称コード内の配列の要素を取り出す時に逐一型

検査が行われることを防ぐことである。次の式を例に説明する。 

array[i].method() 

ここで,arrayはT[]型をもつものとする(Tは総称仮引数とする),かつTはメソッドmethodのインタ

フェースをもつことが制約で指定されているものとする。この式は次のILコードにコンパイルされるかも

しれない。 

ldloc array 

ldloc j 

// j is array index 

readonly. 

ldelema !0   

// loads the pointer to the object 

…   

// load the arguments to the call 

constrained. !0 

callvirt method  

readonly.接頭辞がなければ,ldelemaは!0が参照クラスである場合に型検査を行うだろう。この型

検査は非効率なだけでなく,意味上誤りでもある。ldelemaに対する型検査は,一般には厳格すぎる

typecheckの結果と正確には一致しない。配列が!0の継承クラスを保持していた場合,上に示したコード

はldelemaのtypecheckに失敗するだろう。ソースコードが指示しているとおりに配列自身の代わりに配

列要素のアドレスをとりだす唯一の理由は,値型及び制約付きのcallvirt命令に渡すことができる参照型の

両方に対してうまく働くarray[i]のハンドルが必要だからである。 

配列が参照型の要素を保持している場合,実行時の検査を省略することは,一般的に安全ではないだろ

background image

314 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

う。安全性を確保するためには,このポインタを介してこの配列に対するいかなる変更も行われないこと

を保証しなければならない。上に示した正当性検証規則はこれを保証する。明示的に読込み専用のポイン

タをインスタンスメソッド呼出しのオブジェクトとして渡すことを許すので,これらのポインタは値型に

対しては厳密には読込み専用のポインタではなくなるが,値型に対する型安全についての問題は生じない。 

2.4 

tail.(接頭辞)−現在のメソッドを終了する 

形式 

アセンブリ形式 

定義 

FE 14 

tail. 

後続する呼出しが現メソッドを終了する。 

定義 

tail.接頭辞は,call,calli又はcallvirt命令の直前になければならない。tail.命令は,現在

実行中のメソッドのスタックフレームがもはや必要ではないので,呼出し命令を実行する前に除去できる

ことを示す。その呼出しによって返される値が現在実行中のメソッドの返却値になるので,その呼出しを

メソッド間の飛越しに変換できる。 

評価スタックは,次の呼出しによって転送されようとしている実引数を除いて,空でなければならない。

呼出し命令に後続する命令はretでなければならない。したがって,唯一の妥当なコード列は次のとおり

とする。 

tail.call (又はcalli又はcallvirt) ≪場所の指定≫ 

ret 

適正なCILはcall命令に分岐してはならないが,retに分岐することは許される。スタック上の値は,

呼出されようとしているメソッドに対する実引数だけでなければならない。 

try,filter,catch又はfinallyブロックの外に制御を移すために,tail.call(calli又は

callvirt)命令を使用することはできない(第1章参照)。 

コード識別性セキュリティを危険にさらすので,信頼関係がないコードから信頼されているコードに制

御を移す場合,現在のフレームは破棄できない。したがって,セキュリティ検査は,通常の呼出し命令だ

けを残して,tail.を無視してもよい。 

同様に,呼出しから戻った後の同期領域からの抜け出しを許すために,同期と印付けられたメソッドか

ら抜け出すために使われる場合,tail.接頭辞を無視する。 

tail.接頭辞がある種の場合に従うのを防ぐ実装固有制限があってもよい。このような場合には,処理

系はtail.接頭辞を無視してもかまわないが,プログラムの動作に影響する可能性がある場合には,明確

に文書化すべきである。 

CLI処理系は,呼出し側及び呼出し先が同じアセンブリに格納されることが静的に分かっている場合,

呼出し側が同期領域にない場合,及び呼出し側と呼出し先とが下で述べる“正当性検証可能性”規則に挙

げた条件をすべて満たしている場合には,tail.call要求を尊重する必要がある(tail.接頭辞を“尊

重する”とは,通常の呼出し手順にもどさずに,呼出し側のフレームを除去することを意味する。)。した

がって,CLI実装はtail.calli又はtail.callvirtコード列を尊重する必要はない。 

注記 (根拠)tail.callは,線形空間アルゴリズムを定数空間アルゴリズムに変換することを可

能にする。また,幾つかの言語はtail.callを必要とする。ldloca及びldarga命令が存

在するので,どんな場合にtail.を自動的に挿入できるかを,CILからプラットフォーム固有

のコードに変換するコンパイラが決定することが,常に可能であるとは限らない。 

例外 

なし。 

background image

315 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

適正性 

適正なCILは,上に挙げた制御移行制約に従う。さらに,管理下ポインタが取り除かれようとしている

スタックフレームを指している場合,呼び出されようとしているメソッドにその管理化ポインタを渡すこ

とはできない。呼び出そうとしているメソッドの返却値の型は,現在実行中のメソッドの返却値の型と互

換性のある型でなければならない。 

正当性検証性 

正当性検証は,現在のフレームを指しているポインタを追跡しないから,呼び出そうとしているメソッ

ドにいかなる管理下ポインタも渡さないことを要求する。 

2.5 

unaligned.(接頭辞)−ポインタ命令が境界調整されていない可能性があることを示す 

形式 

アセンブリ形式 

定義 

FE 12<unsigned int8> 

unaligned.≪境界調整≫ 後続するポインタ命令が境界調整されていないかもし

れない 

スタック推移 

..., ≪アドレス≫ ◊ ..., ≪アドレス≫ 

定義 

unaligned.接頭辞は,スタック上の≪アドレス≫[管理外ポインタ(&)又はnative int。]が,直

後のldind,stind,ldfld,stfld,ldobj,stobj,initblk又はcpblk命令の自然な大きさに境

界調整されていない可能性があることを示す。すなわち,ldind.i4命令に対して,≪アドレス≫の境界

調整が4バイトの境界になっていない可能性がある。initblk及びcpblkについては,省略時の境界調

整は,アーキテクチャ依存(32ビットCPUでは4バイト,64ビットCPUでは8バイト。)とする。出力

を32ビット語長に制限しないコード生成器(第1章及び第2章参照)は,unaligned.を使用しなけれ

ばならない。コンパイル時に境界調整が不明な場合,境界調整は8バイトとする。 

≪境界調整≫の値は,1,2又は4でなければならない。これは,生成されたコードが≪アドレス≫をそ

れぞれ1バイト,2バイト又は4バイト境界調整と仮定したほうがよいことを意味する。 

注記 (根拠)cpblk命令に対する境界調整については,論理的に二つの数値(一つはコピー元,も

う一つはコピー先。)が要求されるだろうが,小さいほうの数値だけを指定した場合,性能につ

いて目立った影響はない。 

unaligned.及びvolatile.接頭辞は,どの順番で組み合わせてもよい。これらは,ldind,stind,

ldfld,stfld,ldobj,stobj,initblk又はcpblk命令の直前に先行しなければならない。volatile.

接頭辞は,ldsfld及びstsfld命令に対して使用できる。 

注記 第1章,12.6.6 原子性及びデータ境界調整に関する情報を参照する。 

例外 

なし。 

適正性及び正当性検証可能性 

unaligned.接頭辞は,上に挙げた命令のうちの一つが直後に続かなければならない。 

2.6 

volatile.(接頭辞)−ポインタ参照が揮発性であることを示す 

形式 

アセンブリ形式 

定義 

FE 13 

volatile. 

後続するポインタ参照が揮発性であることを示す。 

スタック推移 

..., ≪アドレス≫ ◊ ..., ≪アドレス≫ 

background image

316 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

定義 

volatile.接頭辞は,その≪アドレス≫が揮発性のアドレス(すなわち,外部から実行中の現在のスレ

ッドに対する参照が行われる可能性があるアドレス。)であることを指定し,その位置から読み込んだ結果

をキャッシュすることはできず,その位置への多重格納は抑止できないことを指示する。あるアクセスを

volatile.として印付けを行うことは,その1回のアクセスだけに効果をもつ。揮発性の位置へのアクセ

スを原子的に行う必要はない(第1章 メモリモデル及び最適化を参照)。 

unaligned.及びvolatile.接頭辞は,どの順番に組み合わせてもよい。これらは,ldind,stind,

ldfld,stfld,ldobj,stobj,initblk又はcpblk命令の直前に先行しなければならない。volatile.

接頭辞だけは,ldsfld及びstsfld命令に対して使用できる。 

例外 

なし。 

適正性及び正当性検証可能性 

volatile.接頭辞は,上に挙げた命令のうちの一つが直後に続かなければならない。 

基本命令 

これらの命令は,基本操作の“チューリング完全な”集合を形成する。これらは,使用するオブジェク

トモデルに依存しない。CTSのオブジェクトモデルと明確に関係している操作については,オブジェクト

モデル命令の箇条に記載する。 

3.1 

add−数値を加算する 

形式 

アセンブリ形式 

定義 

58 

add 

二つの値を加算し,新しい値を返す。 

スタック推移 

…, ≪値1≫, ≪値2≫ ◊ …, ≪結果≫ 

定義 

add命令は,≪値1≫に≪値2≫を加え,その結果をスタックに投入する。整数演算に対しては,オー

バフローは検出しない(オーバフローを検出する加算命令についてはadd.ovfを参照する。)。浮動小数

点数のオーバフローについては,+inf又は-infを返す。 

受理可能な演算対象の型及びそれらに対応する結果のデータの型は,表2 2項数値演算にまとめてあ

る。 

例外 

なし。 

適正性及び正当性検証可能性 

表2 2項数値演算を参照する。 

3.2 

add.ovf.<signed>−オーバフロー検査をしながら整数値を加算する 

形式 

アセンブリ形式 

定義 

D6 

add.ovf 

オーバフロー検査を伴った符号付き整数値の加算。 

D7 

add.ovf.un 

オーバフロー検査を伴った符号なし整数値の加算。 

スタック推移 

…, ≪値1≫, ≪値2≫ ◊ …, ≪結果≫ 

定義 

background image

317 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

add.ovf命令は,≪値1≫と≪値2≫とを加え,その結果をスタックに投入する。受理可能な演算対象

の型及びそれらに対応する結果のデータ型については,表7 オーバフロー算術演算にまとめてある。 

例外 

演算結果を結果の型で表現できない場合,OverflowExceptionを送出する。 

適正性及び正当性検証可能性 

表7 オーバフロー算術演算を参照する。 

3.3 

and−ビット単位の論理積を計算する 

形式 

命令 

定義 

5F 

and 

二つの整数値のビット単位の論理積をとり,整数値を返す。 

スタック推移 

…, ≪値1≫, ≪値2≫ ◊ …, ≪結果≫ 

定義 

and命令は,≪値1≫と≪値2≫とのビット単位の論理積を計算し,その結果をスタックに投入する。

受理可能な演算対象の型及びそれらに対応する結果のデータ型は,表5 整数演算にまとめてある。 

例外 

なし。 

適正性及び正当性検証可能性 

表5 整数演算を参照する。 

3.4 

arglist−実引数並びを取得する 

形式 

アセンブリ形式 

定義 

FE 00 

arglist 

現在のメソッドに対する実引数並びのハンドルを返す。 

スタック推移 

… ◊ …, ≪引数並びハンドル≫ 

定義 

arglist命令は,現在のメソッドの実引数並びを表す非透過なハンドル 

(System.RuntimeArgumentHandle型をもつ)を返す。このハンドルは,現在実行中のメソッドの有

効期間にだけ妥当とする。しかし,現在実行中のメソッドが制御をもつスレッド上にある期間は,このハ

ンドルを他のメソッドに渡すことができる。arglist命令は,実引数の個数が可変のメソッド内でだけ実

行してもよい。 

注記 (根拠)この命令は,C言語の“printf”のような手続を実装するのに使われる“va̲*”マクロ

を実装するために必要になる。System.ArgIteratorのクラスライブラリ実装とともに使う

ことを想定している。 

例外 

なし。 

適正性 

可変個の実引数を受理することを示す呼出し情報をもつメソッドの本体の中以外で,この命令を発行す

ることは不正なCIL生成とする。 

正当性検証可能性 

識別情報が可変個の実引数を受理することを示すメソッドの本体内では,この命令の使用は正当性検証

可能とする。ただし,この命令を実行した結果はSystem.RuntimeArgumentHandleクラスのインスタ

background image

318 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

ンスでなければならない。 

3.5 

beq.<length>−等しい場合に分岐する 

形式 

アセンブリ形式 

定義 

3B <int32> 

beq ≪対象≫ 

等しい場合,≪対象≫に分岐。 

2E <int8> 

beq.s ≪対象≫ 

等しい場合,≪対象≫への分岐。短縮形式。 

スタック推移 

…, ≪値1≫, ≪値2≫ ◊ … 

定義 

beq命令は,≪値1≫が≪値2≫と等しい場合,≪対象≫に制御を移す。その効果は,brtrue ≪対象

≫が後続するceq命令を実行したのと同じとする。≪対象≫は,現在の命令に続く命令の開始位置からの

(beqに対しては4バイト,beq.sに対しては1バイトの)符号付きのオフセットとして表現される。 

受理可能な演算対象の型は,表4 2項比較及び分岐操作にまとめてある。 

対象の命令が一つ以上の接頭辞コードをもっている場合,これらの接頭辞のうち,最初のものにだけ制

御を移すことができる。 

この命令は,try,catch,filter及びfinallyブロックの中に制御を移すこと並びにこれらのブロ

ックの外に制御を移すことはできない(このような制御の移行は,厳しく制限されており,この命令では

なく,leave命令を使用しなければならない。詳細については第1章を参照する。)。 

例外 

なし。 

適正性 

適正なCILは,上の制御移行規則のすべてを遵守し,スタックの最上部二つの項目が,表4 2項比較

及び分岐操作に示した型と一致していることを保証しなければならない。 

正当性検証可能性 

正当性検証可能なコードは,分岐先への考えられるすべての経路に対して,スタック,局所変数及び実

引数の型の一貫性を要求する(1.8参照)。 

3.6 

bge.<length>−以上の場合に分岐する 

形式 

アセンブリ形式 

定義 

3C <int32> 

bge ≪対象≫ 

以上の場合,≪対象≫への分岐。 

2F <int8> 

bge.s ≪対象≫ 

以上の場合,≪対象≫への分岐。短縮形式。 

スタック推移 

…, ≪値1≫, ≪値2≫ ◊ … 

定義 

bge命令は,≪値1≫が≪値2≫以上の場合,≪対象≫に制御を移す。その効果は,brfalse ≪対象≫

が後続するclt.un命令を実行したのと同じとする。≪対象≫は,現在の命令の後ろの命令の開始位置か

らの(begに対しては4バイト,beg.sに対しては1バイトの)符号付きオフセットとして表現される。 

“bge ≪対象≫”命令の効果は,次のものと同じとする。 

− スタックの演算対象が整数のとき,brfalse ≪対象≫が後続するclt。 

− スタックの演算対象が浮動小数点数のとき,brfalse ≪対象≫が後続するclt.un。 

受理可能な演算対象の型は,表4 2項比較及び分岐操作に要約する。 

対象の命令が,一つ以上の接頭辞コードをもっている場合,これらの接頭辞のうち,最初のものにだけ

制御を移すことができる。 

background image

319 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

この命令は,try,catch,filter及びfinallyブロックの中に制御を移すこと並びにこれらのブロ

ックの外に制御を移すことはできない(このような制御の移行は,厳しく制限されており,この命令では

なく,leave命令を使用しなければならない。詳細については第1章を参照する。)。 

例外 

なし。 

適正性 

適正なCILは,上の制御移行規則のすべてを遵守し,スタックの最上部二つの項目が,表4 2項比較

及び分岐操作に示した型と一致していることを保証しなければならない。 

正当性検証可能性 

正当性検証可能なコードは,分岐先への考えられるすべての経路に対して,スタック,局所変数及び実

引数の型の一貫性を要求する(1.8参照)。 

3.7 

bge.un.<length>−以上の場合に分岐する(符号なし又は順序なしで比較) 

形式 

アセンブリ形式 

定義 

41 <int32> 

bge.un ≪対象≫ 

以上の場合,≪対象≫に分岐(符号なし又は順序なし。)。 

34 <int8> 

bge.un.s ≪対象≫ 

以上の場合,≪対象≫に分岐(符号なし又は順序なし。)。短縮形式。 

スタック推移 

…, ≪値1≫, ≪値2≫ ◊ … 

定義 

bge.un命令は,整数値に対しては符号なし,浮動小数点数値に対しては順序なしで比較を行い,≪値

1≫が≪値2≫より大きいか又は等しい場合,≪対象≫に制御を移す。 

“bge.un ≪対象≫”命令の効果は次のものと同じとする。 

− スタックの演算対象が整数のとき,brfalse ≪対象≫が後続するclt.un。 

− スタックの演算対象が浮動小数点数のとき,brfalse ≪対象≫が後続するclt。 

≪対象≫は,現在の命令の後ろの命令の開始位置からの(begに対しては4バイト,beg.sに対しては

1バイトの)符号付きオフセットとして表現される。 

受理可能な演算対象の型については,表4 2項比較及び分岐操作に要約する。 

対象の命令が,一つ以上の接頭辞コードをもっている場合,これらの接頭辞のうち,最初のものにだけ

制御を移すことができる。 

この命令は,try,catch,filter及びfinallyブロックの中に制御を移すこと並びにこれらのブロ

ックの外に制御を移すことはできない(このような制御の移行は,厳しく制限されており,この命令では

なく,leave命令を使用しなければならない。詳細については第1章を参照する。)。 

例外 

なし。 

適正性 

適正なCILは,上の制御移行規則のすべてを遵守し,スタックの最上部二つの項目が,表4 2項比較

及び分岐操作に示した型と一致していることを保証しなければならない。 

正当性検証可能性 

正当性検証可能なコードは,分岐先への考えられるすべての経路に対して,スタック,局所変数及び実

引数の型の一貫性を要求する(1.8参照)。 

3.8 

bgt.<length>−大きい場合に分岐する 

background image

320 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

形式 

アセンブリ形式 

定義 

3D <int32> 

bgt ≪対象≫ 

大きい場合,≪対象≫に分岐。 

30 <int8> 

bgt.s ≪対象≫ 

大きい場合,≪対象≫に分岐。短縮形式。 

スタック推移 

…, ≪値1≫, ≪値2≫ ◊ … 

定義 

bgt命令は,≪値1≫が≪値2≫より大きいとき,≪対象≫に制御を移す。その効果は,brtrue ≪対

象≫が後続するcgt命令を実行したのと同じとする。≪対象≫は,現在の命令の後ろの命令の開始位置か

らの(bgtに対しては4バイト,bgt.sに対しては1バイトの)符号付きオフセットとして表現される。 

受理可能な演算対象の型については,表4 2項比較及び分岐操作に要約する。 

対象の命令が,一つ以上の接頭辞コードをもっている場合,これらの接頭辞のうち,最初のものにだけ

制御を移すことができる。 

この命令は,try,catch,filter及びfinallyブロックの中に制御を移すこと並びにこれらのブロ

ックの外に制御を移すことはできない(このような制御の移行は,厳しく制限されており,この命令では

なく,leave命令を使用しなければならない。詳細については第1章を参照する。)。 

例外 

なし。 

適正性 

適正なCILは,上の制御移行規則のすべてを遵守し,スタックの最上部二つの項目が,表4 2項比較

及び分岐操作に示した型と一致していることを保証しなければならない。 

正当性検証可能性 

正当性検証可能なコードは,分岐先への考えられるすべての経路に対して,スタック,局所変数及び実

引数の型の一貫性を要求する(1.8参照)。 

3.9 

bgt.un.<length>−大きい場合に分岐する(符号なし又は順序なしで比較) 

形式 

アセンブリ形式 

定義 

42 <int32> 

bgt.un ≪対象≫ 

大きい場合に≪対象≫に分岐する(符号なし又は順序なし。)。 

35 <int8> 

bgt.un.s ≪対象≫ 

大きい場合に≪対象≫に分岐する(符号なし又は順序なし。)。短縮形
式。 

スタック推移 

…, ≪値1≫, ≪値2≫ ◊ … 

定義 

bgt.un命令は,整数値に対しては符号なし,浮動小数点数値に対しては順序なしで比較して,≪値1

≫が≪値2≫より大きいとき,≪対象≫に制御を移す。その効果は,brtrue ≪対象≫が後続するcgt.un

命令を実行したのと同じとする。≪対象≫は,現在の命令の後ろの命令の開始位置からの(bgt.unに対

しては4バイト,bgt.un.sに対しては1バイトの)符号付きオフセットとして表現される。 

受理可能な演算対象の型については,表4 2項比較及び分岐操作に要約する。 

対象の命令が,一つ以上の接頭辞コードをもっている場合,これらの接頭辞のうち,最初のものにだけ

制御を移すことができる。 

この命令は,try,catch,filter及びfinallyブロックの中に制御を移すこと並びにこれらのブロ

ックの外に制御を移すことはできない(このような制御の移行は,厳しく制限されており,この命令では

なく,leave命令を使用しなければならない。詳細については第1章を参照する。)。 

background image

321 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

例外 

なし。 

適正性 

適正なCILは,上の制御移行規則のすべてを遵守し,スタックの最上部二つの項目が,表4 2項比較

及び分岐操作に示した型と一致していることを保証しなければならない。 

正当性検証可能性 

正当性検証可能なコードは,分岐先への考えられるすべての経路に対して,スタック,局所変数及び実

引数の型の一貫性を要求する(1.8参照)。 

3.10 ble.<length>−以下の場合に分岐する 

形式 

アセンブリ形式 

定義 

3E <int32> 

ble ≪対象≫ 

以下の場合,≪対象≫に分岐。 

31 <int8> 

ble.s ≪対象≫ 

以下の場合,≪対象≫に分岐。短縮形式。 

スタック推移 

…, ≪値1≫, ≪値2≫ ◊ … 

定義 

ble命令は,≪値1≫が≪値2≫以下の場合,≪対象≫に制御を移す。≪対象≫は,現在の命令の後ろ

の命令の開始位置からの(bleに対しては4バイト,ble.sに対しては1バイトの)符号付きオフセット

として表現される。 

“ble ≪対象≫”命令の効果は次のものと同じとする。 

− スタックの演算対象が整数のとき,brfalse ≪対象≫が後続するcgt。 

− スタックの演算対象が浮動小数点数のとき,brfalse ≪対象≫が後続するcgt.un。 

受理可能な演算対象の型については,表4 2項比較及び分岐操作に要約する。 

対象の命令が,一つ以上の接頭辞コードをもっている場合,これらの接頭辞のうち,最初のものにだけ

制御を移すことができる。 

この命令は,try,catch,filter及びfinallyブロックの中に制御を移すこと並びにこれらのブロ

ックの外に制御を移すことはできない(このような制御の移行は,厳しく制限されており,この命令では

なく,leave命令を使用しなければならない。詳細については第1章を参照する。)。 

例外 

なし。 

適正性 

適正なCILは,上の制御移行規則のすべてを遵守し,スタックの最上部二つの項目が,表3-4 2項比較

及び分岐操作に示した型と一致していることを保証しなければならない。 

正当性検証可能性 

正当性検証可能なコードは,分岐先への考えられるすべての経路に対して,スタック,局所変数及び実

引数の型の一貫性を要求する(1.8参照)。 

3.11 ble.un.<length>−以下の場合に分岐する(符号なし又は順序なしで比較) 

形式 

アセンブリ形式 

定義 

43 <int32> 

ble.un ≪対象≫ 

以下の場合,≪対象≫に分岐(符号なし又は順序なし。)。 

36 <int8> 

ble.un.s ≪対象≫ 

以下の場合,≪対象≫に分岐(符号なし又は順序なし。)。簡易型。 

スタック推移 

…, ≪値1≫, ≪値2≫ ◊ … 

background image

322 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

定義 

ble.un命令は,整数値に対しては符号なし,浮動小数点数値に対しては順序なしで比較して,≪値1

≫が≪値2≫より小さいとき,≪対象≫に制御を移す。≪対象≫は,現在の命令の後ろの命令の開始位置

からの(ble.unに対しては4バイト,ble.un.sに対しては1バイトの)符号付きオフセットとして表

現される。 

“ble.un ≪対象≫”命令の効果は次のものと同じとする。 

− スタックの演算対象が整数のとき,brfalse ≪対象≫が後続するcgt.un。 

− スタックの演算対象が浮動小数点数のとき,brfalse ≪対象≫が後続するcgt。 

受理可能な演算対象の型については,表4 2項比較及び分岐操作に要約する。 

対象の命令が,一つ以上の接頭辞コードをもっている場合,これらの接頭辞のうち,最初のものにだけ

制御を移すことができる。 

この命令は,try,catch,filter及びfinallyブロックの中に制御を移すこと並びにこれらのブロ

ックの外に制御を移すことはできない(このような制御の移行は,厳しく制限されており,この命令では

なく,leave命令を使用しなければならない。詳細については第1章を参照する。)。 

例外 

なし。 

適正性 

適正なCILは,上の制御移行規則のすべてを遵守し,スタックの最上部二つの項目が,表3-4 2項比較

及び分岐操作に示した型と一致していることを保証しなければならない。 

正当性検証可能性 

正当性検証可能なコードは,分岐先への考えられるすべての経路に対して,スタック,局所変数及び実

引数の型の一貫性を要求する(1.8参照)。 

3.12 blt.<length>−小さい場合に分岐する 

形式 

アセンブリ形式 

定義 

3F <int32> 

blt ≪対象≫ 

小さい場合に,≪対象≫に分岐。 

32 <int8> 

blt.s ≪対象≫ 

小さい場合に,≪対象≫に分岐。短縮形式。 

スタック推移 

…, ≪値1≫, ≪値2≫ ◊ … 

定義 

blt命令は,≪値1≫が≪値2≫より小さいとき,≪対象≫に制御を移す。その効果は,brtrue ≪対

象≫が後続するclt命令を実行したのと同じとする。≪対象≫は,現在の命令の後ろの命令の開始位置か

らの(bltに対しては4バイト,blt.sに対しては1バイトの)符号付きオフセットとして表現される。 

受理可能な演算対象の型については,表4 2項比較及び分岐操作に要約する。 

対象の命令が,一つ以上の接頭辞コードをもっている場合,これらの接頭辞のうち,最初のものにだけ

制御を移すことができる。 

この命令は,try,catch,filter及びfinallyブロックの中に制御を移すこと並びにこれらのブロ

ックの外に制御を移すことはできない(このような制御の移行は,厳しく制限されており,この命令では

なく,leave命令を使用しなければならない。詳細については第1章を参照する。)。 

例外 

なし。 

background image

323 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

適正性 

適正なCILは,上の制御移行規則のすべてを遵守し,スタックの最上部二つの項目が,表4 2項比較

及び分岐操作に示した型と一致していることを保証しなければならない。 

正当性検証可能性 

正当性検証可能なコードは,分岐先への考えられるすべての経路に対して,スタック,局所変数及び実

引数の型の一貫性を要求する(1.8参照)。 

3.13 blt.un.<length>−小さい場合に分岐する(符号なし又は順序なしで比較) 

形式 

アセンブリ形式 

定義 

44 <int32> 

blt.un ≪対象≫ 

小さい場合に,≪対象≫に分岐(符号なし又は順序なし。)。 

37 <int8> 

blt.un.s ≪対象≫ 

小さい場合に,≪対象≫に分岐(符号なし又は順序なし。)。短縮形式。 

スタック推移 

…, ≪値1≫, ≪値2≫ ◊ … 

定義 

blt.un命令は,整数値に対しては符号なし,浮動小数点数値に対しては順序なしで比較して,≪値1

≫が≪値2≫より小さいとき,≪対象≫に制御を移す。その効果は,brtrue ≪対象≫が後続するclt.un

命令を実行したのと同じとする。≪対象≫は,現在の命令の後ろの命令の開始位置からの(blt.unに対

しては4バイト,blt.un.sに対しては1バイトの)符号付きオフセットとして表現される。 

受理可能な演算対象の型については,表4 2項比較及び分岐操作に要約する。 

対象の命令が,一つ以上の接頭辞コードをもっている場合,これらの接頭辞のうち,最初のものにだけ

制御を移すことができる。 

この命令は,try,catch,filter及びfinallyブロックの中に制御を移すこと並びにこれらのブロ

ックの外に制御を移すことはできない(このような制御の移行は,厳しく制限されており,この命令では

なく,leave命令を使用しなければならない。詳細については第1章を参照する。)。 

例外 

なし。 

適正性 

適正なCILは,上の制御移行規則のすべてを遵守し,スタックの最上部二つの項目が,表4 2項比較

及び分岐操作に示した型と一致していることを保証しなければならない。 

正当性検証可能性 

正当性検証可能なコードは,分岐先への考えられるすべての経路に対して,スタック,局所変数及び実

引数の型の一貫性を要求する(1.8参照)。 

3.14 bne.un.<length>−等しくないか順序なしである場合に分岐する 

形式 

アセンブリ形式 

定義 

40 <int32> 

bne.un ≪対象≫ 

等しくないか順序なしである場合,≪対象≫に分岐。 

33 <int8> 

bne.un.s ≪対象≫ 

等しくないか順序なしである場合,≪対象≫に分岐。短縮形式。 

スタック推移 

…, ≪値1≫, ≪値2≫ ◊ … 

定義 

bne.un命令は,整数値に対しては符号なし,浮動小数点数値に対しては順序なしで比較して,≪値1

≫が≪値2≫より小さいとき,≪対象≫に制御を移す。その効果は,brfalse ≪対象≫が後続するceq

命令を実行したのと同じとする。≪対象≫は,現在の命令の後ろの命令の開始位置からの(bne.unに対

background image

324 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

しては4バイト,bne.un.sに対しては1バイトの)符号付きオフセットとして表現される。 

受理可能な演算対象の型については,表4 2項比較及び分岐操作に要約する。 

対象の命令が,一つ以上の接頭辞コードをもっている場合,これらの接頭辞のうち,最初のものにだけ

制御を移すことができる。 

この命令は,try,catch,filter及びfinallyブロックの中に制御を移すこと並びにこれらのブロ

ックの外に制御を移すことはできない(このような制御の移行は,厳しく制限されており,この命令では

なく,leave命令を使用しなければならない。詳細については第1章を参照する。)。 

例外 

なし。 

適正性 

適正なCILは,上の制御移行規則のすべてを遵守し,スタックの最上部二つの項目が,表4 2項比較

及び分岐操作に示した型と一致していることを保証しなければならない。 

正当性検証可能性 

正当性検証可能なコードは,分岐先への考えられるすべての経路に対して,スタック,局所変数及び実

引数の型の一貫性を要求する(1.8参照)。 

3.15 br.<length>−無条件分岐 

形式 

アセンブリ形式 

定義 

38 <int32> 

br ≪対象≫ 

≪対象≫に分岐。 

2B <int8> 

br.s ≪対象≫ 

≪対象≫に分岐。短縮形式。 

スタック推移 

…, ◊ … 

定義 

br命令は,無条件に≪対象≫に制御を移す。≪対象≫は,現在の命令の後ろの命令の開始位置からの(br

に対しては4バイト,br.sに対しては1バイトの)符号付きオフセットとして表現される。 

対象の命令が,一つ以上の接頭辞コードをもっている場合,これらの接頭辞のうち,最初のものにだけ

制御を移すことができる。 

この命令は,try,catch,filter及びfinallyブロックの中に制御を移すこと並びにこれらのブロ

ックの外に制御を移すことはできない(このような制御の移行は,厳しく制限されており,この命令では

なく,leave命令を使用しなければならない。詳細については第1章を参照する。)。 

注記 (根拠)評価スタックが空である場合,br命令の代わりにleave命令を使うことができるが,

leave命令を使用すると,CILからプラットフォーム固有のコードにコンパイルするのに必要

な資源が増加し,劣悪なプラットフォーム固有のコードになってしまうかもしれない。したが

って,両方が妥当な場合には,CIL生成器はleave命令よりbr命令を使用するのが望ましい。 

例外 

なし。 

適正性 

適正なCILは,上の制御移行規則をすべて遵守しなければならない。 

正当性検証可能性 

正当性検証可能なコードは,分岐先への考えられるすべての経路に対して,スタック,局所変数及び実

引数の型の一貫性を要求する(1.8参照)。 

background image

325 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

3.16 break−ブレイクポイント命令 

形式 

アセンブリ形式 

定義 

01 

break 

ブレイクポイントに到達したことをデバッガに通知する。 

スタック推移 

…, ◊ … 

定義 

break命令は,デバッグ支援のための命令とする。break命令は,ブレイクポイントに到達したことを

デバッガに通知するようにCILに指示する。インタプリタの状態に対して,これ以外にはいかなる効果も

もたない。 

周囲のコードへの影響を最小にしつつコードにブレイクポイントをはり付けることができるように,

break命令の大きさは可能な限り小さくなっている。 

break命令は,デバッガをトラップするか,何もしないか,又はセキュリティ例外を発生させてもよい。

正確な動作は実装定義とする。 

例外 

なし。 

適正性 

正当性検証可能性 

break命令は常に正当性検証可能とする。 

3.17 brfalse.<length>−偽,null又はゼロである場合に分岐する 

形式 

アセンブリ形式 

定義 

39 <int32> 

brfalse ≪対象≫ 

値がゼロ(偽)である場合に,≪対象≫に分岐。 

2C <int8> 

brfalse.s ≪対象≫ 値がゼロ(偽)である場合に,≪対象≫に分岐。短縮形式。 

39 <int32> 

brnull ≪対象≫ 

値がnullである場合に,≪対象≫に分岐(brfalseの別名。)。 

2C <int8> 

brnull.s ≪対象≫ 

値がnullである場合に,≪対象≫に分岐。短縮形式(brfalse.s
の別名。)。 

39 <int32> 

brzero ≪対象≫ 

値がゼロである場合,≪対象≫に分岐(brfalseの別名。)。 

2C <int8> 

brzero.s ≪対象≫  値がゼロである場合,≪対象≫に分岐(brfalse.sの別名。)。 

スタック推移 

…, ≪値≫ ◊ … 

定義 

brfalse命令は,(int32,int64,オブジェクト参照,管理下ポインタ,管理外ポインタ又はnative 

int型の)≪値≫がゼロ(偽)である場合,≪対象≫に制御を移す。≪値≫が非ゼロ(真)である場合,

実行は次の命令に継続する。 

≪対象≫は,現在の命令の後ろの命令の開始位置からの(brfalseに対しては4バイト,brfalse.s

に対しては1バイトの)符号付きオフセットとして表現される。 

対象の命令が,一つ以上の接頭辞コードをもっている場合,これらの接頭辞のうち,最初のものにだけ

制御を移すことができる。 

この命令は,try,catch,filter及びfinallyブロックの中に制御を移すこと並びにこれらのブロ

ックの外に制御を移すことはできない(このような制御の移行は,厳しく制限されており,この命令では

なく,leave命令を使用しなければならない。詳細については第1章を参照する。)。 

例外 

background image

326 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

なし。 

適正性 

適正なCILは,上の制御移行規則のすべてを遵守し,スタック上に最低でも1個の項目が存在すること

を保証しなければならない。 

正当性検証可能性 

正当性検証可能なコードは,分岐先への考えられるすべての経路に対して,スタック,局所変数及び実

引数の型の一貫性を要求する(1.8参照)。 

3.18 brtrue.<length>−偽でない場合又は非nullである場合に分岐する 

形式 

アセンブリ形式 

定義 

3A <int32> 

brtrue ≪対象≫ 

値が非ゼロ(真)である場合,≪対象≫に分岐。 

2D <int8> 

brtrue.s ≪対象≫ 

値が非ゼロ(真)である場合,≪対象≫に分岐。短縮形式。 

3A <int32> 

brinst ≪対象≫ 

値がnullでないオブジェクト参照である場合,≪対象≫に分岐
(brtrueの別名。)。 

2D <int8> 

brinst.s ≪対象≫ 

値がnullでないオブジェクト参照である場合,≪対象≫に分岐。短
縮形式(brtrue.sの別名。)。 

スタック推移 

…, ≪値≫ ◊ … 

定義 

brtrue命令は,(native int型の)≪値≫が非ゼロ(真)である場合,≪対象≫に制御を移す。≪

値≫がゼロ(偽)である場合,実行は次の命令に継続する。 

≪値≫がオブジェクト参照(O型)のとき,brinst(brtrueの別名。)は,≪値≫がオブジェクトの

インスタンスになっている場合(すなわち,nullオブジェクト参照でない場合,ldnullを参照。)に制

御を移す。 

≪対象≫は,現在の命令の後ろの命令の開始位置からの(brtrueに対しては4バイト,brtrue.sに

対しては1バイトの)符号付きオフセットとして表現される。 

対象の命令が,一つ以上の接頭辞コードをもっている場合,これらの接頭辞のうち,最初のものにだけ

制御を移すことができる。 

この命令は,try,catch,filter及びfinallyブロックの中に制御を移すこと並びにこれらのブロ

ックの外に制御を移すことはできない(このような制御の移行は,厳しく制限されており,この命令では

なく,leave命令を使用しなければならない。詳細については第1章を参照する。)。 

例外 

なし。 

適正性 

適正なCILは,上の制御移行規則のすべてを遵守し,スタック上に最低でも1個の項目が存在すること

を保証しなければならない。 

正当性検証可能性 

正当性検証可能なコードは,分岐先への考えられるすべての経路に対して,スタック,局所変数及び実

引数の型の一貫性を要求する(1.8参照)。 

3.19 call−メソッドの呼出し 

形式 

アセンブリ形式 

定義 

28 <T> 

call ≪メソッド≫ ≪メソッド≫によって記述されるメソッドの呼出し。 

327 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

スタック推移 

…, ≪実引数1≫, ≪実引数2≫ … ≪実引数N≫ ◊ …, ≪返却値≫ (返却値があるとは

限らない。) 

定義 

call命令は,記述子≪メソッド≫で指定されたメソッドを呼び出す。≪メソッド≫は,呼び出すべき

メソッド,その番号,型及びメソッドに渡すためにスタック上におかれた実引数の順番,使用する呼出し

規約を指定するメタデータトークン(methodref,methoddef又はmethodspec,第2章参照)とする

(CIL呼出し手順の詳細な定義については,第1章を参照する。)。call命令は,制御移行前に現在のメ

ソッドの状態を解放することが望ましいことを示すために,tail.接頭辞の直後におくことができる(2.1

参照)。 

メタデータトークンは,その呼出しが,静的メソッド,インスタンスメソッド,仮想メソッド及び大域

関数のいずれに対するものかを決めるのに十分な情報を伝達する。いずれの場合にも,呼出し先アドレス

は,メタデータトークンから完全に決まる(この命令と仮想メソッドを呼び出すためのcallvirt命令と

の違いに注意する。callvirtによって呼び出される仮想メソッドは,callvirtの前に投入されている

インスタンス参照の正確な型に依存する呼出し先アドレスとする。次を参照する。)。 

メソッドが,メタデータトークンによって指定されたクラスに存在しない場合,そのメソッドを定義す

る最派生クラスを検索するためにすべての基底クラスを検索し,そのメソッドを呼び出す。 

注記 (根拠)これは“基底クラスの呼出し”動作を実現する。 

実引数は,左から右の順に,スタック上におかれる。すなわち,最初の実引数を計算してスタックにお

き,次に2番目の実引数の順におかれる。次に三つの重要な特殊事項を示す。 

1) インスタンスメソッド(又は仮想メソッド,次を参照する。)の呼出しは,利用者に可視な実引数の

前に,そのインスタンス参照(thisポインタ)を投入する。メタデータに格納されて伝達された

識別情報は,仮引数並びの中に,thisポインタのエントリを含んでいない。しかし,メソッドが

thisポインタを渡すことを要求するかどうか示すために(HASTHISと呼ばれる。)ビットを使用

する[第2章参照(値型のメソッドの呼出しに対しては,thisポインタは,インスタンス参照で

はなく,管理下ポインタとする。)]。 

2) call(callvirtではなくcall)を使用する仮想メソッドを呼び出すことは妥当とする。これは,

呼び出されようとしているオブジェクトから動的に指定されるのではなく,≪メソッド≫によって

指定されたクラスを使用することで,メソッドが解決されることを示す。これは例えば,“super

のメソッド”(すなわち,静的に分かっている親クラスのメソッド。)への呼出しをコンパイルする

ために使われる。 

3) 委譲のInvokeメソッドは,call又はcallvirt命令のいずれでも呼出し可能であることに注意

する。 

例外 

システムセキュリティが呼出し先のメソッドへの呼出し側のアクセスを認めない場合,

System.SecurityExceptionを送出する。実行時ではなく,CILをプラットフォーム固有のコードに

変換する時に,セキュリティ検査を行ってもよい。 

クラス内の非公開メソッド又は限定公開メソッドへの不当なアクセスを行おうとした場合,

System.MethodAccessExceptionを送出する可能性がある。 

存在しないメソッドに直接アクセスしようとすると,System.MissingMethodExceptionを送出す

background image

328 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

る可能性がある。 

適正性 

適正なCILは,スタックが呼び出されようとしているメソッドの実引数の正しい個数及び型を保持して

いることを保証する。 

正当性検証可能性 

call命令の典型的な使用法について,正当性検証は,(a)≪メソッド≫が妥当なmethodref,

methoddef又はmethodspecトークンを参照していること,(b)スタック上のオブジェクトの型がメソ

ッド呼出しの期待している型と一致していること,(c)メソッドが呼出し元からアクセス可能であること,

及び(d)メソッドが抽象メソッドではないこと(すなわち,メソッドが実装をもっていること)を検査す

る。 

call命令は,オブジェクトの基底クラス構築子を呼び出すか,又は,適切な構築子を呼び出すことに

よって値型のメモリ位置を初期化するために用いてもよい。それらの両方は正当性検証によって特殊な事

例として扱われる。tail.で修飾されたcallも特殊な事例とする。 

対象のメソッドが大域的である(型の外側で定義されている。)場合,メソッドは静的でなければならな

い。 

ボックス化した値型以外のインスタンス上のfinalになっていない仮想メソッドを呼び出すために

callオプコードを使った場合,正当性検証は,呼び出されようとしているメソッドへのインスタンス参

照がldarg.s 0又はldarg 0の結果であること,及び呼出し側の本体がstarg.s 0,starg 0又は

ldarga.s 0,ldarga 0を含んでいないことを検査する。 

注記 (根拠)これは,finalになっていない仮想メソッドを呼び出す仮想でないメソッドは,そのサ

ブクラスのメソッドが,同じthisオブジェクト参照を使うそのクラスのスーパークラスの一

つを呼び出す場合にだけ正当性検証可能であることを意味する。ここで,同じthisであるこ

とは容易に確かめられるものとする。これは,上書き実装がスーパークラスの実装を効果的に

隠ぺいし,そのクラス階層の外部のコードが上書き実装をう(迂)回できないことを意味する。 

封印されていないクラス階層については,悪意のあるコードが,クラスの上書き実装をう(迂)

回しようとする場合に,クラス階層を拡張しようと試みる可能性がある。しかし,これは,上

書き実装をもつクラスではなく悪意のある型のオブジェクト上でしか行えない。このような仕

組みにすることによって,セキュリティ上の懸念の多くを緩和している。 

3.20 calli−メソッドの間接呼出し 

形式 

アセンブリ形式 

定義 

29 <T> 

calli ≪呼出し元記
述子≫ 

≪呼出し元記述子≫によって記述された実引数で,スタック上で示さ
れたメソッドを呼び出す。 

スタック推移 

…, ≪実引数1≫, ≪実引数2≫ … ≪実引数N≫, ≪関数≫ ◊ …, ≪返却値≫ (返却

値があるとは限らない) 

定義 

calli命令は,実引数≪実引数1≫ ... ≪実引数N≫を伴って,≪関数≫(メソッド入口点へのポイン

タ)を呼び出す。これらの実引数の型は,識別情報≪呼出し元記述子≫によって記述される(CIL呼出し

手順の記述については第1章を参照する。)。制御移行前に現在のメソッドの状態を解放するのが望ましい

ことを示すために,calli命令の直前にtail.接頭辞をおいてもよい。呼出しが,もとのメソッドより高

background image

329 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

い信頼度のメソッドに制御を移す場合には,スタックフレームは解放されないだろう。その代わりに,あ

たかもtail.接頭辞が指定されなかったかのように,黙って実行を継続するだろう。 

“より高い信頼度”の呼出し先とは,アクセス許可集合が呼出し側の許可集合の厳密なスーパーセット

になっていることと定義する。 

≪関数≫実引数は,≪呼出し元記述子≫(独立した識別情報に対するメタデータトークン。)によって記

述された引数を伴って正当に呼び出すことができる(対象とする計算機の)プラットフォーム固有のコー

ドへのポインタであると仮定される。そのようなポインタは,ldftn又はldvirtftn命令を使うことで

作成できる。また,プラットフォーム固有のコードから渡ってくるかもしれない。 

独立した識別情報は,呼出し規約のほかに,渡されようとしている仮引数の個数及び型を指定する(第

2章参照)。呼出し規約を動的に検査することはない。したがって,calli命令を用いているコードは,呼

出し先が実際には指定された呼出し規約を使っていない場合,正しく動作しないだろう。 

実引数は,左から右の順に,スタック上におかれる。すなわち,最初の実引数を計算してスタックにお

き,次に2番目の実引数の順におかれる。インスタンス又は仮想メソッドに対する実引数を作成するコー

ド列は,利用者に可視な実引数の前にインスタンス参照(thisポインタ又はnullであってはならない。)

をスタックに入れなければならない(値型のメソッドの呼出しについては,thisポインタは,インスタン

ス参照ではなく,管理下ポインタとする。)。 

例外 

システムセキュリティが呼出し先のメソッドへの呼出し側のアクセスを認めない場合,

System.SecurityExceptionを送出する可能性がある。実行時ではなく,CILをプラットフォーム固

有のコードに変換する時に,セキュリティ検査を行う可能性がある。 

適正性 

適正なCILは,関数ポインタが,≪呼出し元記述子≫によって指定されたものと一致する識別情報をも

ち,実引数が呼出し先の関数の仮引数の型と正しく一致するメソッドのアドレスを含んでいなければなら

ない。 

正当性検証可能性 

正当性検証は,≪関数≫がldftn又はldvirtfnによって生成された関数へのポインタであることを

検査する。 

3.21 ceq−等しいかどうか比較する 

形式 

アセンブリ形式 

定義 

FE 01 

ceq 

プッシュ≪値1≫が≪値2≫と等しい場合,スタックに(int32型
の)1を入れ,そうでなければ0を入れる。 

スタック推移 

…, ≪値1≫, ≪値2≫ ◊ …, ≪結果≫ 

定義 

ceq命令は,≪値1≫と≪値2≫とを比較する。≪値1≫が≪値2≫と等しい場合,(int32型の)1を

スタックに入れる。そうでなければ,(int32型の)0をスタックに入れる。 

浮動小数点数については,数が順序なし(いずれか一方又は両方がNaN。)である場合,ceqは0を返

す。無限大を示す数同士は互いに等しい。 

受理可能な演算対象の型については,表4 2項比較及び分岐操作に要約する。 

例外 

background image

330 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

なし。 

適正性 

適正なCILは,スタック上に,表4 2項比較及び分岐操作で指定したものと一致する型の二つの値を

供給する。追加の正当性検証要件はない。 

正当性検証可能性 

追加の正当性検証要件はない。 

3.22 cgt−大きいかどうか比較する 

形式 

アセンブリ形式 

定義 

FE 02 

cgt 

≪値1≫ > ≪値2≫である場合に,(int32型の)1を投入する。そ
うでなければ,0を投入する。 

スタック推移 

…, ≪値1≫, ≪値2≫ ◊ …, ≪結果≫ 

定義 

cgt命令は,≪値1≫と≪値2≫とを比較する。≪値1≫が厳密に≪値2≫より大きい場合,(int32型

の)1をスタックに入れる。そうでなければ,(int32型の)0をスタックに入れる。 

浮動小数点数については,cgtは,数値が順序なしである場合(すなわち,一方又は両方の実引数が

NaNである場合。),0を返す。 

無限大の値は,通常の数値に対してIEC 60559:1989に従って順序付けられる(例えば,+無限大>5.0

>−無限大。)。 

受理可能な演算対象の型については,表4 2項比較及び分岐操作に要約する。 

例外 

なし。 

適正性 

適正なCILは,スタック上に,表4 2項比較及び分岐操作で指定したものと一致する型の二つの値を

供給する。 

正当性検証可能性 

追加の正当性検証要件はない。 

3.23 cgt.un−大きいかどうか比較する(符号なし又は順序なしで比較) 

形式 

アセンブリ形式 

定義 

FE 03 

cgt.un 

符号なし又は順序なしについて,≪値1≫ > ≪値2≫である場合,
(int32型の)1をスタックに入れる。そうでなければ,0を入れ
る。 

スタック推移 

…, ≪値1≫, ≪値2≫ ◊ …, ≪結果≫ 

定義 

cgt.un命令は,≪値1≫と≪値2≫とを比較する。次の場合に,(int32型の)1をスタックに入れる。 

− 浮動小数点数については,≪値1≫が≪値2≫より厳密に大きいか,又は,≪値1≫が≪値2≫に対し

て順序付けられない場合。 

− 整数値については,符号なしの数とみなしたときに,≪値1≫が≪値2≫より厳密に大きい場合。 

そうでなければ,(int32型の)0をスタックに入れる。 

無限大の値は,通常の数値に対してIEC 60559:1989に従って順序付けられる(例えば,+無限大>5.0

background image

331 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

>−無限大。)。 

受理可能な演算対象の型については,表4 2項比較及び分岐操作に要約する。 

例外 

なし。 

適正性 

適正なCILは,スタック上に,表4 2項比較及び分岐操作で指定したものと一致する型の二つの値を

供給する。 

正当性検証可能性 

追加の正当性検証要件はない。 

3.24 ckfinite−有限実数値について検査する 

形式 

アセンブリ形式 

定義 

C3 

ckfinite 

値が有限数でない場合,ArithmeticExceptionを送出する。 

スタック推移 

…, ≪値≫ ◊ …, ≪値≫ 

定義 

(浮動小数点数の)値が“非数”を示す値(NaN),又は,+若しくは-の無限大である場合,ckfinite

命令はArithmeticExceptionを送出する。例外を送出しない場合,ckfiniteはスタックに値を残す。

値が浮動小数点数でない場合,実行時の動作は未規定とする。 

例外 

値がNaN又は無限大である場合,System.ArithmeticExceptionを送出する。 

適正性 

適正なCILは≪値≫が浮動小数点数であることを保証する。 

正当性検証可能性 

追加の正当性検証要件はない。 

3.25 clt−未満かどうか比較する 

形式 

アセンブリ形式 

定義 

FE 04 

clt 

≪値1≫ < ≪値2≫である場合,(int32型の)1をスタッ
クに入れる。それ以外の場合は0を入れる。 

スタック推移 

…, ≪値1≫, ≪値2≫ ◊ …, ≪結果≫ 

定義 

clt命令は≪値1≫と≪値2≫とを比較する。≪値1≫が厳密に≪値2≫未満である場合,(int32型の)

1をスタックに入れる。そうでなければ,(int32型の)0をスタックに入れる。 

浮動小数点数については,数値が順序なしである場合(すなわち片方又は両方の実引数がNaNである場

合),cltは0を返す。 

IEC 60559:1989に従って,無限大の値は正常な数値について順序付けられる(例えば,+無限大 > 5.0 > -

無限大。)。 

受理可能な演算対象の型については,表4 2項比較及び分岐操作に要約する。 

例外 

なし。 

background image

332 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

適正性 

適正なCILは,表4 2項比較及び分岐操作に示したものと一致する型の二つの値をスタック上に提供

する。 

正当性検証可能性 

追加の正当性検証要件はない。 

3.26 clt.un−未満かどうか比較する(符号なし又は順序なしで比較) 

形式 

アセンブリ形式 

定義 

FE 05 

clt.un 

≪値1≫ < ≪値2≫で,かつ,符号なし又は順序なしである場合,
(int32型の)1をスタックに入れる。それ以外の場合,0を入れ
る。 

スタック推移 

…, ≪値1≫, ≪値2≫ ◊ …, ≪結果≫ 

定義 

clt.un命令は≪値1≫と≪値2≫を比較する。次の場合に,(int32型の)1をスタックに入れる。 

− 浮動小数点数に対しては,≪値1≫が厳密に≪値2≫未満であるか,又は≪値2≫について,≪値1≫

が順序付けできない場合。 

− 整数値に対しては,符号なしの数とみなした場合に,≪値1≫が厳密に≪値2≫未満である場合。 

そうでなければ,(int32型の)0をスタックに投入する。 

IEC 60559:1989に従って,無限大の値は正常な数値について順序付けられる(例えば,+無限大 > 5.0 > -

無限大。)。 

受理可能な演算対象の型については,表4 2項比較及び分岐操作に要約する。 

例外 

なし。 

適正性 

適正なCILは,表4 2項比較及び分岐操作に示したものと一致する型の二つの値をスタック上に提供

する。 

正当性検証可能性 

追加の正当性検証要件はない。 

3.27 conv.<to type>−データ変換 

形式 

アセンブリ形式 

定義 

67 

conv.i1 

int8に変換し,int32をスタックに入れる。 

68 

conv.i2 

int16に変換し,int32をスタックに入れる。 

69 

conv.i4 

int32に変換し,int32をスタックに入れる。 

6A 

conv.i8 

int64に変換し,int64をスタックに入れる。 

6B 

conv.r4 

float32に変換し,Fをスタックに入れる。 

6C 

conv.r8 

float64に変換し,Fをスタックに入れる。 

D2 

conv.u1 

unsigned int8に変換し,int32をスタックに入れる。 

D1 

conv.u2 

unsigned int16に変換し,int32をスタックに入れる。 

6D 

conv.u4 

unsigned int32に変換し,int32をスタックに入れる。 

6E 

conv.u8 

unsigned int64に変換し,int64をスタックに入れる。 

D3 

conv.i 

native intに変換し,native intをスタックに入れる。 

E0 

conv.u 

native unsigned intに変換し,native intをスタックに入れ
る。 

background image

333 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

76 

conv.r.un 

符号なし整数を浮動小数点数に変換し,Fをスタックに入れる。 

スタック推移 

…, ≪値≫ ◊ …, ≪結果≫ 

定義 

スタックの最上部の値を,オプコード中で指定された型に変換し,その変換した値をスタックの最上部

に入れる。4バイト未満の整数値を評価スタックにロードする場合,4バイト未満の整数値は(native int

ではなく)int32に拡張され,浮動小数点数はF型に変換されることに注意。 

浮動小数点数から整数値への変換は,ゼロ方向への切捨てを行う。float64からfloat32に変換する

場合,精度が失われてもよい。絶対値が大きすぎてfloat32に格納できない場合,IEC 60559:1989の正

の無限大(値が正である場合。)又はIEC 60559:1989の負の無限大(値が負である場合。)を返す。ある整

数型から別の型への変換中にオーバフローが発生した場合,特に通知することなく上位ビットを切り捨て

る。結果がint32より小さい場合,スロットを満たすために値を符号拡張する。 

浮動小数点型を整数型に変換する時にオーバフローが生じる場合,又は,整数に変換されようとしてい

る浮動小数点数がNaNである場合,返却値の値は未規定とする。conv.r.un操作はスタックから整数を

取り出し,符号なしと解釈して,その整数を表現する浮動小数点数に置き換える。float32がその整数型

を精度の損失なく表現するのに十分な幅である場合,float32とし,そうでない場合,float64とする。 

受理可能な演算対象の型及び対応する結果データの型については,表8 変換操作に要約する。 

例外 

いかなる例外も送出されない。結果型が適切に結果の値を表現することができない場合に例外を送出す

る命令については,conv.ovfを参照する。 

適正性 

適正なCILは,スタックの上に,表8 変換操作で指定された型の値を少なくとも一つもつ。 

正当性検証可能性 

表8 変換操作は,正当性検証されたコードにおいて受理可能な型の制限された集合を規定する。 

3.28 conv.ovf.<to type>−オーバフロー検出を備えたデータ変換 

形式 

アセンブリ形式 

定義 

B3 

conv.ovf.i1 

int8に変換する(int32としてスタックに入れる。)。オーバフロー
に関する例外を送出する。 

B5 

conv.ovf.i2 

int16に変換する(int32としてスタックに入れる。)。オーバフロ
ーに関する例外を送出する。 

B7 

conv.ovf.i4 

int32に変換する(int32としてスタックに入れる。)。オーバフロ
ーに関する例外を送出する。 

B9 

conv.ovf.i8 

int64に変換する(int64としてスタックに入れる。)。オーバフロ
ーに関する例外を送出する。 

B4 

conv.ovf.u1 

unsigned int8に変換する(int32としてスタックに入れる。)。
オーバフローに関する例外を送出する。 

B6 

conv.ovf.u2 

unsigned int16に変換する(int32としてスタックに入れる。)。
オーバフローに関する例外を送出する。 

B8 

conv.ovf.u4 

unsigned int32に変換する(int32としてスタックに入れる。)。
オーバフローに関する例外を送出する。 

BA 

conv.ovf.u8 

unsigned int64に変換する(int64としてスタックに入れる。)。
オーバフローに関する例外を送出する。 

D4 

conv.ovf.i 

native intに変換する(native intとしてスタックに入れる。)。
オーバフローに関する例外を送出する。 

background image

334 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

D5 

conv.ovf.u 

native unsigned intに変換する(native intとしてスタック
に入れる。)。オーバフローに関する例外を送出する。 

スタック推移 

…, ≪値≫ ◊ …, ≪結果≫ 

定義 

スタックの最上部の値を,オプコード中で指定された型に変換し,その変換した値をスタックの最上部

に入れる。変換結果が変換先の型で表現できない場合,例外を送出する。 

浮動小数点数から整数値への変換では,値はゼロ方向に切り捨てられる。4バイト未満の整数値は,評

価スタック上で(native intではなく)int32に拡張されることに注意する。 

受理可能な演算対象の型及び対応する結果データの型は表8 変換操作に要約する。 

例外 

結果が,結果型で表現できない場合,System.OverflowExceptionを送出する。 

適正性 

適正なCILは,スタックの上に,表8 変換操作で指定された型の値を少なくとも一つもつ。 

正当性検証可能性 

表8 変換操作は,正当性検証されたコードにおいて受理可能な型の制限された集合を規定する。 

3.29 conv.ovf.<to type>.un−オーバフロー検出を備えた符号なしデータ変換 

形式 

アセンブリ形式 

定義 

82 

conv.ovf.i1.un 

unsignedをint8に変換する(int32としてスタック上におく。)。
オーバフローに関する例外を送出する。 

83 

conv.ovf.i2.un 

unsignedをint16に変換する(int32としてスタック上におく。)。
オーバフローに関する例外を送出する。 

84 

conv.ovf.i4.un 

unsignedをint32に変換する(int32としてスタック上におく。)。
オーバフローに関する例外を送出する。 

85 

conv.ovf.i8.un 

unsignedをint64に変換する(int64としてスタック上におく。)。
オーバフローに関する例外を送出する。 

86 

conv.ovf.u1.un 

unsignedをunsigned int8に変換する(int32としてスタック
上におく。)。オーバフローに関する例外を送出する。 

87 

conv.ovf.u2.un 

unsignedをunsigned int16に変換する(int32としてスタッ
ク上におく。)。オーバフローに関する例外を送出する。 

88 

conv.ovf.u4.un 

unsignedをunsigned int32に変換する(int32としてスタッ
ク上におく。)。オーバフローに関する例外を送出する。 

89 

conv.ovf.u8.un 

unsignedをunsigned int64に変換する(int32としてスタッ
ク上におく。)。オーバフローに関する例外を送出する。 

8A 

conv.ovf.i.un 

unsignedをnative intに変換する(native intとしてスタッ
ク上におく。)。オーバフローに関する例外を送出する。 

8B 

conv.ovf.u.un 

unsignedをnative unsigned intに変換する(native int
としてスタック上におく。)。オーバフローに関する例外を送出する。 

スタック推移 

…, ≪値≫ ◊ …, ≪結果≫ 

定義 

スタックの最上部の値を,オプコード中で指定された型に変換し,その変換した値をスタックの最上部

に入れる。変換結果が変換先の型で表現できない場合,例外を送出する。スタックの最上部の項目は,変

換の前は符号なしの値として扱われる。 

background image

335 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

浮動小数点数から整数値への変換では,値はゼロ方向に切り捨てられる。4バイト未満の整数値は,評

価スタック上で(native intではなく)int32に拡張されることに注意する。 

受理可能な演算対象の型及び対応する結果データの型は表8 変換操作に要約する。 

例外 

結果が,結果型で表現できない場合,System.OverflowExceptionを送出する。 

適正性 

適正なCILは,スタックの上に,表8 変換操作で指定された型の値を少なくとも一つもつ。 

正当性検証可能性 

表8 変換操作は,正当性検証されたコードにおいて受理可能な型の制限された集合を規定する。 

3.30 cpblk−メモリ間でデータをコピーする 

形式 

命令 

定義 

FE 17 

cpblk 

メモリ間でデータをコピーする。 

スタック推移 

…, ≪コピー先アドレス≫, ≪コピー元アドレス≫, ≪大きさ≫ ◊ … 

定義 

cpblk命令は,(native int型又は&の)アドレス≪コピー元アドレス≫から(native int型又は

&の)アドレス≪コピー先アドレス≫に≪大きさ≫バイトコピーする。コピー元とコピー先の領域とが重

なっている場合,cpblkの動作は未規定とする。 

cpblkは,≪コピー先アドレス≫及び≪コピー元アドレス≫の両方が計算機の自然な大きさに境界調整

されていると仮定する(ただし,unaligned.接頭辞命令が指定されている場合を除く。unaligned.接

頭辞命令を参照する。)。cpblk命令の操作は,直前に先行するvolatile.又はunaligned.接頭辞命令

によって変更できる。 

注記 (根拠)cpblkは,(任意のバイト数の列ではなく)構造体のコピーを行うことを想定してい

る。CLIによって割り付けられるすべての構造体は,実行中のプラットフォームに自然になる

ように境界調整されている。したがって,コンパイラは,最終的にコードを実行するのが32

ビット又は64ビットプラットフォームのいずれかを意識してcpblk命令を生成する必要はな

い。 

例外 

不当なアドレスが検出された場合,System.NullReferenceExceptionを送出する可能性がある。 

適正性 

CILが上に規定した条件を満たしている。 

正当性検証可能性 

cpblk命令は正当性検証可能ではない。 

3.31 div−値を除算する 

形式 

アセンブリ形式 

定義 

5B 

div 

二つの値を除算し,商又は浮動小数点の結果を返す。 

スタック推移 

…, ≪値1≫, ≪値2≫ ◊ …, ≪結果≫ 

定義 

≪結果≫ = ≪値1≫ div ≪値2≫は,次の条件を満たす。 

background image

336 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

|≪結果≫| = |≪値1≫| / |≪値2≫|,かつ, 

sign(≪値1≫) = sign(≪値2≫)である場合,sign(≪結果≫) = +,sign(≪値1≫) ~= sign(≪値2≫)である場

合,sign(≪結果≫) = - 

div命令は≪結果≫を計算して,スタックに入れる。 

整数除算はゼロ方向への切捨てを行う。 

浮動小数点式の除算はIEC 60559:1989に従う。特に,有限数の0による除算は,正しく符号つきの無限

大を算出する。また, 

0 / 0 = NaN 

infinity / infinity = NaN. 

X / infinity = 0 

とする。 

受理可能な演算対象の型及び対応する結果データの型は,表2 2項数値演算に要約する。 

例外 

整数演算は,結果を結果の型で表現できない場合,System.ArithmeticExceptionを送出する(こ

れは,≪値1≫が表現可能な最小の整数値であり,≪値2≫が-1のときに発生する可能性がある。)。 

≪値2≫がゼロである場合,整数演算はSystem.DivideByZeroExceptionを送出する。 

浮動小数点演算は,例外を送出しない(浮動小数点演算は,例外を送出するのではなく,NaN又は無限

大を生成する。)。 

例 

+14 div +3は4とする。 

+14 div -3は-4とする。 

-14 div +3は-4とする。 

-14 div -3は4とする。 

適正性及び正当性検証可能性 

表2 2項数値演算を参照する。 

3.32 div.un−値をunsignedとみなして除算する 

形式 

アセンブリ形式 

定義 

5C 

div.un 

二つの値をunsignedとみなして除算し,商を返す。 

スタック推移 

…, ≪値1≫, ≪値2≫ ◊ …, ≪結果≫ 

定義 

div.un命令は,≪値1≫及び≪値2≫の両方を符号なし整数とみなして,≪値1≫除する≪値2≫を計

算し,結果をスタックに入れる。 

受理可能な演算対象の型及び対応する結果データの型は,表5 整数演算に要約する。 

例外 

≪値2≫がゼロである場合,System.DivideByZeroExceptionを送出する。 

例 

+5 div.un +3は1とする。 

+5 div.un -3は0とする。 

background image

337 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

-5 div.un +3は14316557630(0x55555553)とする。 

-5 div.un -3は0とする。 

適正性及び正当性検証可能性 

表5 整数演算を参照する。 

3.33 dup−スタックの最上部の値を複製する 

形式 

アセンブリ形式 

定義 

25  

dup 

スタックの最上部の値を複製する。 

スタック推移 

…, ≪値≫ ◊ …, ≪値≫, ≪値≫ 

記述 

dup命令は,スタックの最上部の要素を複製する。 

例外 

なし。 

適正性及び正当性検証可能性 

追加の正当性検証要件はない。 

3.34 endfilter−例外処理フィルタ節を終了する 

形式 

アセンブリ形式 

定義 

FE 11 

Endfilter 

例外処理フィルタ節を終了する。 

スタック推移 

…, ≪値≫ ◊ … 

定義 

例外のfilter節から復帰するために使われる(例外の議論については,第1章の例外処理の箇条を参

照する。)。≪値≫(int32型で値の特定の集合の中の一つでなければならない。)が,filter節から返

される。≪値≫は,次のうちのいずれかであることが望ましい。 

− 例外ハンドラの探索を継続するためには,exception̲continue̲search (0)を指定する。 

− このフィルタ節に関連したハンドラが見つかるまで,finallyブロックを実行する,例外処理の第2

段階を実行するためには,exception̲execute̲handler (1)を指定する。その後,ハンドラを実行

する。 

それ以外の整数値を使用した結果は,未規定とする。 

フィルタの入口点は,メソッドの例外表に示すように,フィルタのコードブロック中の(字句的に)最

初の命令でなければならない。endfilterは,フィルタのコードブロック中の(字句的に)最後の命令

でなければならない(したがって,endfilterは,任意の単一のフィルタブロックに対して,1個だけ存

在できる。)。endfilter命令を実行した後,制御は,論理的にCLI例外処理機構にもどる。 

例外機構を介さずにfilterブロックに制御を移すことはできない。throw命令の使用又は最後の

endfilterを実行すること以外に,制御をfilterブロックの外に移すことはできない。特に,filter

ブロックの中でret又はleave命令を実行することは妥当ではない。filterブロックの中にtryブロ

ックを埋め込むのは妥当ではない。filterブロックの内部で例外を送出した場合,その例外は途中で遮

断され,値exception̲continue̲searchが返される。 

例外 

なし。 

background image

338 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

適正性 

適正なCILは上に規定した制御移行についての制限に従うことを保証する。 

正当性検証可能性 

スタックは,ちょうど一つの(int32型の)項目を含んでいなければならない。 

3.35 endfinally−例外ブロックのfinally又はfault節を終了する 

形式 

アセンブリ形式 

定義 

DC 

endfault 

例外ブロックのfault節を終了する。 

DC 

endfinally 

例外ブロックのfinally節を終了する。 

スタック推移 

… ◊ … 

定義 

例外ブロックのfinally又はfault節から復帰する(詳細については第1章の例外処理の箇条を参照

する。)。 

例外ハンドラが呼び出されるまで,スタック巻戻しを継続できるようにfinally又はfault節の終了

を合図する。endfinally又はendfault命令は,CLI例外機構に制御をもどす。さらに,leave命令

で限定公開のブロックから抜け出した場合には,連鎖中の次のfinally節を探索する。例外によって限

定公開のブロックから抜け出した場合は,CLIは次のfinally又はfault節を探索するか,例外処理の

最初の経路中の選択された例外ハンドラに入る。 

endfinally命令は,finallyブロックの中に構文的に1回だけ出現できる。endfilter命令とは異

なり,ブロックがendfinally命令で終わらなければならないという要件はない。また,ブロック内に必

要なだけendfinally命令が存在することができる。これら同様の制限が,endfault命令及びfault

ブロックについても適用される。 

例外機構を介さずにfinallyブロックに制御を移すことはできない。throw命令の使用又は

endfinally(又はendfault)を実行すること以外に,制御をfinally(又はfault)ブロックの外

に移すことはできない。特に,finally(又はfault)ブロックの中でret又はleave命令を実行する

こと,及びfinally(又はfault)ブロックから“抜け出す”することは妥当ではない。 

endfault命令及びendfinally命令は別名とし,同じオプコードになっていることに注意する。

endfinallyは副作用として評価スタックを空にする。 

例外 

なし。 

適正性 

適正なCILは上に規定した制御移行についての制限に従う。 

正当性検証可能性 

追加の正当性検証要件はない。 

3.36 initblk−指定した値でメモリブロックを初期化する 

形式 

アセンブリ形式 

定義 

FE 18 

initblk 

メモリブロック内のすべてのバイトに指定されたバイト値を設定する。 

スタック推移 

…, ≪アドレス≫, ≪値≫, ≪大きさ≫ ◊ … 

定義 

background image

339 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

initblk命令は,(native int型又は&の)≪アドレス≫から始まる(unsigned int32型の)≪大

きさ≫バイトの領域に(unsigned int8型の)≪値≫を設定する。initblkは,≪アドレス≫が計算機

の自然な大きさに境界調整されていると仮定する(ただし,unaligned.接頭辞命令が指定されている場

合を除く。unaligned.接頭辞命令を参照する。)。 

注記 (根拠)initblkは,(任意のバイト列ではなく)構造体のコピーを行うことを想定している。

CLIによって割り付けられるすべての構造体は,実行中のプラットフォームに自然になるよう

に境界調整されている。したがって,コンパイラは,最終的にコードを実行するのが32ビット

又は64ビットプラットフォームのいずれかを意識してinitblk命令を生成する必要はない。 

initblk命令の操作は,直前に先行するvolatile.又はunaligned.接頭辞命令によって変更できる。 

例外 

不当なアドレスを検出した場合,System.NullReferenceExceptionを送出する可能性がある。 

適正性 

適正なCILは,上に規定した制限に従う。 

正当性検証可能性 

initblk命令は正当性検証可能ではない。 

3.37 jmp−メソッドへの飛越し 

形式 

アセンブリ形式 

定義 

27 <T> 

jmp ≪メソッド≫ 

現在実行中のメソッドを抜け出し,指定されたメソッドに飛び越す。 

スタック推移 

… ◊ … 

定義 

≪メソッド≫で指定されたメソッドに制御を移す。≪メソッド≫はメタデータトークンmethodref又

はmethoddefのいずれかとする(第2章参照)。現在の実引数は飛越し先のメソッドに引き継がれる。 

この命令が実行されるとき,評価スタックは空でなければならない。飛越し先のアドレスの呼出し規約,

実引数の個数及び型は,現在実行中のメソッドのものと一致しなければならない。 

try,filter,catch,fault若しくはfinallyブロック,又は同期領域の外部に制御を移すために,

jmp命令を使うことはできない。これを実行した場合の結果は未規定とする(第1章参照)。 

例外 

なし。 

適正性 

適正なCILコードは,上に規定した制御フローの制限に従う。 

正当性検証可能性 

jmp命令は正当性検証可能ではない。 

3.38 ldarg.<length>−スタック上への実引数のロード 

形式 

アセンブリ形式 

定義 

FE 09 <unsigned int16> ldarg ≪番号≫ 

≪番号≫番目の実引数をスタックにロードする。 

0Eの<unsigned int8> 

ldarg.s ≪番号≫ ≪番号≫番目の実引数をスタックにロードする。短縮形式。 

02 

ldarg.0 

0番目の実引数をスタックにロードする。 

03 

ldarg.1 

1番目の実引数をスタックにロードする。 

04 

ldarg.2 

2番目の実引数をスタックにロードする。 

05 

ldarg.3 

3番目の実引数をスタックにロードする。 

background image

340 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

スタック推移 

… ◊ …, ≪値≫ 

定義 

ldarg ≪番号≫命令は,メソッドに渡された≪番号≫番目の実引数を評価スタックに投入する。実引数

は,0から増加方向に付番する。ldarg命令は,渡された引数からコピーすることによって,値型又は組

込みの値をスタックにロードするために使うことができる。値の型は,現在実行中のメソッドの識別情報

によって指定された実引数の型と同じとする。 

ldarg.0,ldarg.1,ldarg.2及びldarg.3命令は,最初の四つの実引数のうちのいずれか一つを

ロードするために,効率的に符号化された形式とする。ldarg.s命令は,4〜255番目の実引数をロード

するために効率的に符号化された形式とする。 

可変長の実引数並びをとる手続については,ldarg命令は先頭の固定の実引数に対してだけ使用できる。

識別情報の可変部分の実引数に対しては使用できない(arglist命令を参照する。)。 

長さが4バイトより短い整数値を保持する実引数については,スタックにロードする時にint32型に拡

張する。浮動小数点数については,プラットフォーム固有の大きさ(F型)に拡張する。 

例外 

なし。 

適正性 

適正なCILは,≪番号≫が妥当な実引数の添字になっていることを保証する。 

正当性検証可能性 

正当性検証がどのようにスタックにロードされた値の型を決定するかについての詳細は,1.8を参照する。 

3.39 ldarga.<length>−実引数アドレスをロードする 

形式 

アセンブリ形式 

定義 

FE 0A <unsigned 
int16> 

ldarga ≪引数番号≫ 

≪引数番号≫の実引数のアドレスを取り出す。 

0Fの<unsigned int8> ldarga.s ≪引数番号≫ 

≪引数番号≫の実引数のアドレスを取り出す。短縮形式。 

スタック推移 

…, ◊ …, ≪引数番号で示された位置の引数のアドレス≫ 

定義 

ldarga命令は,≪引数番号≫番目の実引数のアドレス(&型,すなわち,管理下ポインタ。)を取得す

る。実引数は0から増加方向に付番する。アドレスは,常に対象となる計算機に自然な境界に境界調整さ

れるだろう(cpblk及びinitblk参照)。実引数番号0〜255に対しては,短縮形式(ldarga.s)を使

用することが望ましい。 

可変長の実引数並びをとる手続については,ldarga命令は先頭の固定の実引数に対してだけ使用でき

る。識別情報の可変部分の実引数に対しては使用できない。 

注記 (根拠)ldargaは,byref仮引数渡しを行うために使われる(第1章参照)。それ以外の場

合には,ldarg及びstargを使用することが望ましい。 

例外 

なし。 

適正性 

適正なCILは,≪引数番号≫が妥当な引数の添字になっていることを保証する。 

background image

341 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

妥当性検証可能性 

正当性検証がどのようにスタックにロードされた値の型を決定するかについての詳細は,1.8を参照する。 

3.40 ldc.<type>−数値定数のロード 

形式 

アセンブリ形式 

定義 

20 <int32> 

ldc.i4 ≪数値≫ 

int32型の≪数値≫をint32としてスタックに入れる。 

21 <int64> 

ldc.i8 ≪数値≫ 

int64型の≪数値≫をint64としてスタックに入れる。 

22 <float32> 

ldc.r4 ≪数値≫ 

float32型の≪数値≫をFとしてスタックに入れる。 

23 <float64> 

ldc.r8 ≪数値≫ 

float64型の≪数値≫をFとしてスタックに入れる。 

16 

ldc.i4.0 

0をint32としてスタックに入れる。 

17 

ldc.i4.1 

1をint32としてスタックに入れる。 

18 

ldc.i4.2 

2をint32としてスタックに入れる。 

19 

ldc.i4.3 

3をint32としてスタックに入れる。 

1A 

ldc.i4.4 

4をint32としてスタックに入れる。 

1B 

ldc.i4.5 

5をint32としてスタックに入れる。 

1C 

ldc.i4.6 

6をint32としてスタックに入れる。 

1D 

ldc.i4.7 

7をint32としてスタックに入れる。 

1E 

ldc.i4.8 

8をint32としてスタックに入れる。 

15 

ldc.i4.m1 

-1をint32としてスタックに投入する。 

15 

ldc.i4.M1 

int32型の-1をint32としてスタックに入れる(ldc.i4.m1の

別名。)。 

1F<int8> 

ldc.i4.s ≪数値≫ 

≪数値≫をint32としてスタックに入れる。短縮形式。 

スタック推移 

… ◊ …, ≪数値≫ 

定義 

ldc ≪数値≫命令は数値≪数値≫又は何らかの定数をスタックに入れる。整数-128〜127に対しては短

い符号化形式が存在する(特に-1〜8に対しては短い符号化形式がある。)。すべての短い符号化形式は,4

バイトの整数をスタックに入れる。長い符号化形式は,8バイト整数並びに4バイト及び8バイトの浮動

小数点数に対しても使用する。短縮形式に収まらない4バイトの値についても同様に長い符号化形式を使

用する。 

8バイトの整数定数をスタックに入れる方法は,3通りある。 

1) 32ビットを超えるビット数でしか表現できない定数については,ldc.i8命令を使用する。 

2) 9〜32ビットが必要な定数に対しては,ldc.i4命令に続けてconv.i8を使用する。 

3) 8ビット以下で表現できる定数については,短縮形式の命令に続けてconv.i8を使用する。 

IEC 60559:1989の64ビットの数値より広い値域又は高い精度をもつ浮動小数点定数を表現する方法は

ない。これは,これらの表現がアーキテクチャ間で可搬性がないことによる。 

例外 

なし。 

適正性 

正当性検証可能性 

ldc命令は常に正当性検証可能とする。 

3.41 ldftn−メソッドポインタをロードする 

形式 

アセンブリ形式 

定義 

FE 06 <T> 

ldftn ≪メソッド≫ 

≪メソッド≫が参照するメソッドへのポインタをスタックに入れる。 

background image

342 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

スタック推移 

… ◊ …, ≪関数≫ 

定義 

ldftn命令は,≪メソッド≫[メタデータトークン,methoddf又はmethodrefのいずれか(第2章

参照)。]によって記述されたメソッドを実装するプラットフォーム固有のコードへの管理外ポインタ

(native int型)をスタックに入れる。スタックに入れられた値は,それが管理下メソッド(又は管理

下コードから管理外コードに推移させるスタブ。)を参照している場合,calli命令を使って呼び出すこ

とができる。 

返される値は,≪メソッド≫によって指定された呼出し規約を使用するプラットフォーム固有のコード

を指す。したがって,メソッドポインタは,(例えば,コールバックルーチンとして)管理外のプラットフ

ォーム固有のコードに渡すことができる。この命令によって算出されたアドレスは,この目的(例えば,

プラットフォーム固有の版のCILインタプリタが使用できない場合に,CILインタプリタへの再入。)のた

めに特別に生成された仲介コードを指している可能性があることに注意する。 

注記 この命令の実装方法としては様々な選択肢がある。概念的には,この命令は,仮想計算機の評

価スタック上に指定されたメソッドのアドレスの表現をおく。プラットフォーム固有のコード

にとっては,これは,基盤になっている計算機,プラットフォーム固有の呼出し規約及びVES

(JIT,インタプリタ,スレッド化されたコードなど)の実装技術に応じて,(指定どおりの)

アドレス,アドレスを含むデータ構造又はアドレスを算出するために使用できる任意の値であ

り得る。 

例外 

なし。 

適正性 

適正なCILは,メソッドが妥当なmethoddef又はmethodrefトークンでなければならない。 

正当性検証可能性 

正当性検証は,スタックに入れられた型がメソッドポインタであることを考慮して,スタックに入れら

れた型をnative int型より詳細に追跡する。そのようなメソッドポインタは,その後calli,又は,

委任を構築することで,使用できる。 

3.42 ldind.<type> − スタック上に間接的に値をロードする 

形式 

アセンブリ形式 

定義 

46 

ldind.i1 

int8型の値をint32としてスタックに間接ロードする。 

48 

ldind.i2 

int16型の値をint32としてスタックに間接ロードする。 

4A 

ldind.i4 

int32型の値をint32としてスタックに間接ロードする。 

4C 

ldind.i8 

int64型の値をint64としてスタックに間接ロードする。 

47  

ldind.u1 

unsigned int8型の値をint32としてスタックに間接ロードする。 

49 

ldind.u2 

unsigned int16型の値をint32としてスタックに間接ロードす
る。 

4B 

ldind.u4 

unsigned int32型の値をint32としてスタックに間接ロードす
る。 

4E 

ldind.r4 

float32型の値をFとしてスタックに間接ロードする。 

4C 

ldind.u8 

int64型の値をint64としてスタックに間接ロードする
(ldind.i8の別名。)。 

4F 

ldind.r8 

float64型の値をFとしてスタックに間接ロードする。 

background image

343 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

4D 

ldind.i 

native int型の値をnative intとしてスタックに間接ロードす
る。 

50 

ldind.ref 

object ref型の値をOとしてスタックに間接ロードする。 

スタック推移 

…, ≪アドレス≫ ◊ …, ≪値≫ 

定義 

ldind命令は,アドレス≪アドレス≫(管理外ポインタ,native int,管理下ポインタ又は&。)から

間接的に値をスタックにロードする。ロード元の値は命令接尾辞によって指示する。すべてのldind命令

は,対応する組込みの値クラスを指定するldobj命令の短縮形式とする。 

4バイト未満の整数値は,評価スタックにロードされる時に,int32(native intではない。)に拡張

されることに注意する。浮動小数点数は,評価スタックにロードされる時に,F型に変換される。 

適正なCILは,ポインタ型の作法と矛盾しないようにldind命令を使用することを保証する。 

≪アドレス≫によって指定されたアドレスは,<type>の自然な境界にあった位置を指していなければな

らない。そうでなければ,NullReferenceExceptionが発生するかもしれない(ただし,unaligned.

接頭辞命令が指定されている場合を除く。unaligned.接頭辞命令を参照する。境界調整については第1

章で規定する。)。アドレスを返すすべてのCIL命令(例えばldloca及びldarga。)の結果は,安全に

境界調整されている。1バイトより大きいデータ型については,バイト順序は対象のCPUに依存する。バ

イト順序に依存するコードは,すべてのプラットフォーム上で動作するとは限らない。 

ldind命令の動作は,直前に先行するvolatile.接頭辞又はunaligned.接頭辞によって変更できる。 

注記 (根拠)CLIが符号拡張すべきかゼロ拡張すべきかを知ることが可能なように,小さな整数型

に対する符号付き及び符号なし形式が必要となる。利便性を向上させるため,ldind.u8及び

異形のldind.u4を提供する。ldind.u8は,ldind.i8の別名とする。ldind.u4と

ldind.i4とは異なるオプコードをもつが,その効果は同じとする。 

例外 

不当なアドレスが検出された場合,System.NullReferenceExceptionを送出する可能性がある。 

適正性 

適正なCILは,常にポインタの型と矛盾しない方法でldind命令を使用する。 

正当性検証可能性 

正当性検証可能なコードに対しては,スタック上のアドレスは管理下ポインタでなければならない。ま

た,命令形式は上の表に示したとおりにポインタの型と一致していなければならない。 

3.43 ldloc−局所変数をスタックにロードする 

形式 

アセンブリ形式 

定義 

FE 0C <unsigned 
int16> 

ldloc ≪添字≫ 

添字≪添字≫の局所変数をスタック上にロードする。 

11<unsigned int8> ldloc.s ≪添字≫ 添字≪添字≫の局所変数をスタック上にロードする。短縮形式。 

06 

ldloc.0 

局所変数0をスタックにロードする。 

07 

ldloc.1 

局所変数1をスタックにロードする。 

08 

ldloc.2 

局所変数2をスタックにロードする。 

09 

ldloc.3 

局所変数3をスタックにロードする。 

スタック推移 

… ◊ …, ≪値≫ 

定義 

background image

344 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

ldloc ≪添字≫命令は,局所変数番号≪添字≫の内容を評価スタックに入れる。ここで,局所変数は0

から増加方向に付番される。局所変数は,メソッドのlocalsinitが真である場合にだけ,0で初期化さ

れる(第1章参照)。ldloc.0,ldloc.1,ldloc.2及びldloc.3命令は,最初の四つの局所変数にア

クセスするための効率的な符号化形式を提供する。ldloc.s命令は,局所変数4〜255をアクセスするた

めの効率的な符号化形式を提供する。 

値の型は,メソッドヘッダ中で指定された局所変数の型と同じとする(第1章参照)。 

長さが4バイト未満の局所変数は,スタックに入れられる時に,int32型に拡張される。浮動小数点の

値は,プラットフォーム固有の大きさ(F型)に拡張される。 

例外 

このメソッドに対するlocalsinitビットが設定されておらず,このメソッドを含んでいるアセンブリ

がSystem.SecurityPermission.SkipVerification(CILが自動の有限の代入分析を実行しない。)

を与えられていない場合,System.VerificationExceptionを送出する。 

適正性 

適正なCILは,≪添字≫が妥当な局所添字になっていることを保証する。 

ldloc ≪添字≫命令に対しては,≪添字≫は,0〜65534の範囲(境界を含む。)でなければならない(明

確に65535は妥当ではない。)。 

注記 (根拠)65535を除外するのは,実践的な理由による。ありそうな実装は,指定されたメソッ

ドに対する局所変数の合計値のほかに,局所変数の添字を追跡するのにも2バイト整数を使う

だろう。65535を妥当な添字とした場合,メソッド中の局所変数の番号を追跡するために,大

きさがより大きい整数が必要になっていただろう。 

正当性検証可能性 

正当性検証可能なコードについては,この命令は,未初期化の値をロードしないことを保証しなければ

ならない。すなわち,メソッドのlocalsinitビットが設定されていることによって明示的に初期化され

るか,又は,以前の命令によって初期化されていなければならない(CLIは有限代入解析を行う。)。 

正当性検証が局所変数の型を決定する方法についての詳細は1.8を参照する。 

3.44 ldloca.<length>−局所変数アドレスをロードする 

形式 

アセンブリ形式 

定義 

FE 0D <unsigned 
int16> 

ldloca ≪添字≫ 

添字≪添字≫の局所変数のアドレスをロードする。 

12 <unsigned int8> ldloca.s ≪添字≫ 添字≪添字≫の局所変数のアドレスをロードする。短縮形式。 

スタック推移 

… ◊ …, ≪アドレス≫ 

定義 

ldloca命令は,局所変数番号≪添字≫のアドレスをスタックに入れる。局所変数は0から増加方向に

付番する。スタックに入れられた値は,ldind及びstindのような命令を使って既に正しく境界調整さ

れている。結果は管理下ポインタ(&型)とする。ldloca.s命令は,局所変数0〜255に使用するために

効率的な符号化を供給する(ldlocaによって取得されるアドレスはldindに対する実引数として使うこ

とができるため,ldlocaの対象の局所変数は,ldind命令で示したように境界調整されていなければな

らない。)。 

例外 

background image

345 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

このメソッドに対するlocalsinitビットが設定されておらず,このメソッドを含んでいるアセンブリ

がSystem.SecurityPermission.SkipVerification(CILが自動の有限の代入分析を実行しない。)

を与えられていない場合,System.VerificationExceptionを送出する。 

適正性 

適正なCILは,≪添字≫が妥当な局所添字になっていることを保証する。 

ldloca ≪添字≫命令については,≪添字≫は0〜65534の範囲(境界を含む。)でなければならない(明

確に,65535は妥当ではない。)。 

注記 (根拠)65535を除外するのは,実践的な理由による。ありそうな実装は,指定されたメソッ

ドに対する局所変数の合計値のほかに,局所変数の添字を追跡するのにも2バイト整数を使う

だろう。65535を妥当な添字とした場合,メソッド中の局所変数の番号を追跡するために,大

きさがより大きい整数が必要になっていただろう。 

妥当性検証可能性 

正当性検証が局所変数の型を決定する方法についての詳細は1.8を参照する。 

正当性検証可能なコードについては,この命令は,未初期化の値のアドレスをロードしないことを保証

しなければならない。すなわち,メソッドのlocalsinitビットが設定されていることによって明示的に

初期化されるか,又は,以前の命令によって初期化されていなければならない(CLIは有限代入解析を行

う。)。 

3.45 ldnull−nullポインタをロードする 

形式 

アセンブリ形式 

定義 

14 

ldnull 

null参照をスタックに入れる。 

スタック推移 

… ◊ …, ≪null値≫ 

定義 

ldnullは,null参照(O型)をスタックに入れる。この命令は,位置が有効になる前又は無効になった

後に,その位置を初期化するために使われる。 

注記 (根拠)ldnullは冗長であると思われるかもしれない。ldnullの代わりにldc.i4.0又は

ldc.i8.0を使用しないのはなぜか。答えは,ldnullが不定な大きさのnullを与えるからで

ある。実際には存在しないが,ldc.i命令と類似している。しかし,たとえ,仮にCILがldc.i

命令を取り込む予定だったとしても,型追跡が容易になるという意味で,ldnull命令をもっ

ていることは,正当性検証アルゴリズムにとって依然として有益だろう。 

例外 

なし。 

適正性 

正当性検証可能性 

ldnull命令は,常に正当性検証可能であり,正当性検証が任意の異なる参照型と互換であるとみなす

値を生成する。 

3.46 leave.<length>−コードの保護領域から抜け出す 

形式 

アセンブリ形式 

定義 

DD <int32> 

leave ≪対象≫ 

コードの限定公開領域から抜け出す。 

DE <int8> 

leave.s ≪対象≫ 

コードの限定公開領域から抜け出す。短縮形式。 

background image

346 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

スタック推移 

…, ◊ 

定義 

leave命令は,無条件に≪対象≫に制御を移す。≪対象≫は,現在の命令に後続する命令の開始位置か

らの符号付きオフセット(leaveでは4バイト,leave.sでは1バイト。)として表現される。 

leave命令は,br命令に似ているが,通常の分岐命令がブロック内で制御を移すようなブロック内で

しか使えないのに対して,leave命令は,try,filter又はcatchブロックを抜け出すのに使用できる。

leave命令は,評価スタックを空にし,適切な取り囲んでいるfinallyブロックを実行することを保証

する。 

finallyブロックを抜け出すためにleave命令を使用することは妥当ではない。例外ハンドラのコー

ドの生成を容易にするため,catchブロックの中で,関連するtryブロック内の任意の命令に制御を移

すためにleave命令を使うことは妥当とする。 

leave命令は,多重入れ子ブロックを抜け出すために使用できる(第1章参照)。 

命令が一つ以上の接頭辞コードをもっている場合,最初の接頭辞に対してだけ制御を移すことができる。 

例外 

なし。 

適正性 

適正なCILは,算出された制御移行先が現在実行中のメソッド内になければならない。 

正当性検証可能性 

詳細については1.8を参照する。 

3.47 localloc−局所動的予備メモリ領域中の領域を割り付ける 

形式 

アセンブリ形式 

定義 

FE 0F 

localloc 

ローカル予備メモリ領域から領域を割り付ける。 

スタック推移 

≪大きさ≫ ◊ ≪アドレス≫ 

定義 

localloc命令は,局所動的予備メモリ領域から≪大きさ≫(native unsigned int型又はU4)バ

イトを割り付け,割り付けられた最初のバイトの(非管理下ポインタ,native int型の)アドレスを返

す。メソッドのlocalsinitフラグが真である場合,返されるメモリのブロックは0に初期化される。そ

うでなければ,そのメモリのブロックの初期値は未規定とする。メモリの領域は新しく割り付けられる。

現メソッドから復帰する時,その局所予備メモリ領域は再利用可能になる。 

stind命令を用いて任意の組込みデータ型が格納できるように,また,ldind命令を用いて任意の組込

みデータ型をロードできるように,≪アドレス≫を境界調整する。 

localloc命令は,例外ブロック内,すなわち,filter,catch,finally及びfault内に現れてはな

らない。 

注記 (根拠)locallocは,実行時に大きさを計算しなければならない局所集約を生成するために

使用する。locallocは,Cの組込みのallocaメソッドとして使用できる。 

例外 

要求に応じるためのメモリが不足している場合,System.StackOverflowExceptionを送出する。 

適正性 

background image

347 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

適正なCILは,項目≪大きさ≫を除いて評価スタックが空でなければならない。 

正当性検証可能性 

この命令は正当性検証可能ではない。 

3.48 mul−値を乗算する 

形式 

アセンブリ形式 

定義 

5A 

mul 

値を乗算する。 

スタック推移 

…, ≪値1≫, ≪値1≫ ◊ …, ≪結果≫ 

定義 

mul命令は,≪値1≫に≪値2≫を乗じて,結果をスタックに入れる。整数演算では,オーバフロー時

には,警告なしに上位ビットを切り捨てる(mul.ovf参照)。 

浮動小数点型については,0×無限大=NaNとする。 

受理可能な演算対象の型及びそれらに対応する結果のデータの型は,表2 2項数値演算にまとめてあ

る。 

例外 

なし。 

適正性及び正当性検証可能性 

表2 2項数値演算を参照する。 

3.49 mul.ovf.<type> − オーバフロー検査をしながら整数値を乗算する 

形式 

アセンブリ形式 

定義 

D8 

mul.ovf 

符号付き整数値を乗算する。符号付きの結果が同じ大きさに入らなけ
ればならない。 

D9 

mul.ovf.un 

符号なし整数値を乗算する。符号なしの結果が同じ大きさに入らなけ
ればならない。 

スタック推移 

…, ≪値1≫, ≪値2≫ ◊ …, ≪結果≫ 

定義 

mul.ovf命令は,整数≪値1≫と≪値2≫とを乗算し,結果をスタックに入れる。結果が結果の型に入

らない場合,例外を送出する。 

受理可能な演算対象の型及びそれらに対応する結果のデータの型は,表7 オーバフロー算術演算にま

とめてある。 

例外 

結果が結果型で表現できない場合,System.OverflowExceptionを送出する。 

適正性及び正当性検証可能性 

表8 変換操作を参照する。 

3.50 neg − 符号を反転する 

形式 

アセンブリ形式 

定義 

65 

neg 

値の符号を反転する。 

スタック推移 

…, ≪値≫ ◊ …, ≪結果≫ 

定義 

background image

348 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

neg命令は,≪値≫の符号を反転し,結果をスタックに入れる。返却値の型は演算対象の型と同じとす

る。 

整数値の符号反転は,標準的な2の補数をとる方法による符号反転とする。特例として,(対応する正の

数がない)最大の負数の符号反転の結果は,最大の負数となる。このオーバフローを検出するには,

sub.ovf命令(すなわち,0からの減算。)を使用する必要がある。 

浮動小数点数の符号反転は,オーバフローを起こさない。NaNを符号反転すると,NaNを返す。 

受理可能な演算対象の型及びそれらに対応する結果のデータの型は,表3 単項数値演算にまとめてあ

る。 

例外 

なし。 

適正性及び正当性検証可能性 

表3 単項数値演算を参照する。 

3.51 nop − 操作なし 

形式 

アセンブリ形式 

定義 

00 

nop 

何もしない。 

スタック推移 

…, ◊ …, 

定義 

nop命令は何もしない。この命令は,バイトコードにパッチをあてる場合に,領域を埋めるために使う

ことを意図している。 

例外 

なし。 

適正性 

正当性検証可能性 

nop命令は常に正当性検証可能とする。 

3.52 not − ビット単位の補数を計算する 

形式 

アセンブリ形式 

定義 

66 

not 

ビット単位の補数をとる 

スタック推移 

…, ≪値≫ ◊ …, ≪結果≫ 

定義 

not命令は,スタックの最上部の整数値のビット単位の補数を計算し,スタックに結果を入れる。返却

値の型は演算対象の型と同じとする。 

受理可能な演算対象の型及びそれらに対応する結果のデータの型は,表5 整数演算にまとめてある。 

例外 

なし。 

適正性及び正当性検証可能性 

表5 整数演算をする。 

3.53 or − ビット単位の論理和を計算する 

形式 

命令 

定義 

60 

or 

二つの整数値のビット単位の論理和を計算し,整数を返す。 

background image

349 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

スタック推移 

…, ≪値1≫, ≪値2≫ ◊ …, ≪結果≫ 

定義 

or命令は,スタック最上部の二つの値のビット単位の論理和を計算し,結果をスタックに入れる。 

受理可能な演算対象の型及びそれらに対応する結果のデータの型は,表5 整数演算にまとめてある。 

例外 

なし。 

適正性及び正当性検証可能性 

表5 整数演算をする。 

3.54 pop − スタックの最上部の要素を取り除く 

形式 

アセンブリ形式 

定義 

26 

pop 

スタックからの≪値≫を取り出す。 

スタック推移 

…, ≪値≫ ◊ … 

定義 

pop命令は,スタックから最上部の要素を取り除く。 

例外 

なし。 

適正性 

正当性検証可能性 

追加の要件はない。 

3.55 rem − 剰余を計算する 

形式 

アセンブリ形式 

定義 

5D 

rem 

ある値を別の値で除した剰余を計算する。 

スタック推移 

…, ≪値1≫, ≪値2≫ ◊ …, ≪結果≫ 

定義 

rem命令は,≪値1≫を≪値2≫で除算し,剰余≪結果≫をスタックに入れる。 

受理可能な演算対象の型及びそれらに対応する結果のデータの型については,表2 2項数値演算にま

とめてある。 

整数の演算対象について 

≪結果≫ = ≪値1≫ rem ≪値2≫は,次の条件を満たす。 

divを0方向への切捨てを行う除算命令とすると, 

≪結果≫ = ≪値1≫ - ≪値2≫ × (≪値1≫ div ≪値2≫),かつ, 

0 ≦ |≪結果≫| < |≪値2≫|,かつ, 

sign(≪結果≫) = sign(≪値1≫)。 

浮動小数点数の演算対象について 

remは,整数演算の場合と同様に定義されている。ただし,≪値2≫がゼロである場合又は≪値1≫が

無限大である場合には,≪結果≫はNaNとする。≪値2≫が無限大である場合,≪結果≫は≪値1≫とす

る。この定義は,IEC 60559:1989規格における浮動小数点の剰余の規定とは異なる。IEC 60559:1989規格

background image

350 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

は,《値1》div 《値2》は,ゼロ方向への切捨てではなく,最も近い整数になると規定している。

System.Math.IEEERemainder(第4章参照)は,IEC 60559:1989の動作を提供する。 

例外 

≪値2≫がゼロである場合,整数演算はSystem.DivideByZeroExceptionを送出する。 

≪値1≫が表現可能な最小の整数値である場合又は≪値2≫が-1である場合,整数演算は

System.ArithmeticExceptionを送出する可能性がある。 

正当性検証可能性 

表2 2項数値演算を参照する。 

3.56 rem.un − 符号なしの整数剰余を計算する 

形式 

アセンブリ形式 

定義 

5E 

rem.un 

符号なしの値を別の符号なしの値で除した剰余を計算する。 

スタック推移 

…, ≪値1≫, ≪値2≫ ◊ …, ≪結果≫ 

定義 

rem.un命令は,≪値1≫を≪値2≫で除算し,その剰余≪結果≫をスタックに入れる(remは,実引数

を符号付き整数とみなすが,rem.unは,実引数を符号なし整数とみなす。)。 

≪結果≫ = ≪値1≫ rem.un ≪値2≫は次の条件を満たす。 

≪結果≫ = ≪値1≫ - ≪値2≫ × (≪値1≫ div.un ≪値2≫),かつ, 

0 ≦ ≪結果≫ < ≪値2≫, 

ここで,div.unは符号なし除算命令とする。rem.un命令は,浮動小数点数に対しては未規定とする。 

受理可能な演算対象の型及びそれらの対応する結果のデータ型は,表5 整数演算にまとめてある。 

例外 

≪値2≫がゼロである場合,整数演算はSystem.DivideByZeroExceptionを送出する。 

例  

+5 rem.un +3は2  

(+5 div.un +3 = 

1) 

+5 rem.un -3は5  

(+5 div.un -3 = 

0) 

-5 rem.un +3は2  

( -5 div.un +3 = 

1431655763又は0x55555553) 

-5 rem.un -3は-5又は0xfffffffb ( -5 div.un -3 = 0) 

適正性及び正当性検証可能性 

表5 整数演算を参照する。 

3.57 ret − メソッドから復帰する 

形式 

アセンブリ形式 

定義 

2A 

ret 

メソッドから復帰する。復帰と同時に値を返すこともできる。 

スタック推移 

 呼出し側の評価スタック上の≪返却値≫(常に存在するとは限らない) ◊ 

…, 呼び出された側の評価スタック上の≪返却値≫ (常に存在するとは限らない) 

定義 

background image

351 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

現在実行中のメソッドから復帰する。返却値がある場合,現在実行中のメソッドの返却値の型が,スタ

ックの最上部から取り出され,現在実行中のメソッドを呼び出したメソッドのスタック上にコピーされる

値の型を決定する。現在実行中のメソッドのための評価スタックは,返却される値を除き,空でなければ

ならない。 

ret命令は,try,filter,catch及びfinallyブロックの外へ制御を移すために使用することはで

きない。try又はcatchの内部から外部へ制御を移すためには,取り囲んでいるすべての例外ブロック

の外のret命令の制御移行先を指定したleave命令を使用せよ。filter及びfinallyブロックは,論

理上それらのコードが埋め込まれたメソッドではなく,例外処理の一部であるため,正しく生成されたCIL

は,filter及びfinallyの内部からの復帰するメソッドを実行しない(第1章参照)。 

例外 

なし。 

適正性 

適正なCILは,上の制御移行についての制約に従う。 

正当性検証可能性 

正当性検証は,≪返却値≫の型が現在実行中のメソッドの宣言された返却値の型と互換性のある型にな

っていることを要求する。 

3.58 shl − 整数を左シフトする 

形式 

アセンブリ形式 

定義 

62 

shl 

整数を左シフト(ゼロ拡張)し,整数を返す。 

スタック推移 

…, ≪値≫, ≪シフト量≫ ◊ …, ≪結果≫ 

定義 

shl命令は,(int32,int64又はnative int型の)≪値≫を≪シフト量≫で指定されたビット数だ

け左シフトする。≪シフト量≫は,int32,int64又はnative int型とする。≪シフト量≫が≪値≫

の幅以上である場合,返却値は未規定とする。受理可能な演算対象の型及び対応する結果の型についての

詳細は,表6 シフト演算を参照する。 

例外 

なし。 

適正性及び正当性検証可能性 

表5 整数演算を参照する。 

3.59 shr − 整数を右シフトする 

形式 

アセンブリ形式 

定義 

63 

shr 

整数を右シフト(符号拡張)し,整数を返す。 

スタック推移 

…, ≪値≫, ≪シフト量≫ ◊ …, ≪結果≫ 

定義 

shr命令は,(int32,int64又はnative int型の)≪値≫を≪シフト量≫で指定されたビット数だ

け右シフトする。≪シフト量≫は,int32又はnative int型とする。≪シフト量≫が≪値≫の幅以上

である場合,返却値は未規定とする。shrは,各シフト操作において高位ビットを複製し,≪結果≫の元の

値の符号を維持する。受理可能な演算対象の型及び対応する結果の型の詳細については,表6 シフト演

background image

352 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

算を参照する。 

例外 

なし。 

適正性及び正当性検証可能性 

表5 整数演算を参照する。 

3.60 shr.un − 整数を符号なしで右シフトする 

形式 

アセンブリ形式 

定義 

64 

shr.un 

整数を右シフト(ゼロ拡張)し,整数を返す。 

スタック推移 

…, ≪値≫, ≪シフト量≫ ◊ …, ≪結果≫ 

定義 

shr.un命令は,(int32,int64及びnative int型の)≪値≫を≪シフト量≫で指定されたビット

数だけ右シフトする。≪シフト量≫は,int32又はnative int型とする。≪シフト量≫が≪値≫の幅

以上である場合,返却値は未規定とする。shr.unは,各シフト操作においてゼロのビットを挿入する。

受理可能な演算対象の型及び対応する結果の型の詳細については,表6 シフト演算を参照する。 

例外 

なし。 

適正性及び正当性検証可能性 

表5 整数演算を参照する。 

3.61 starg.<length> − 実引数スロットに値を格納する 

形式 

アセンブリ形式 

定義 

FE 0B <unsigned 
int16> 

starg ≪数値≫ 

≪数値≫番目の実引数に≪値≫を格納する。 

10 <unsigned int8> starg.s ≪数値≫ ≪数値≫番目の実引数に≪値≫を格納する。短縮形。 

スタック推移 

…, ≪値≫ ◊ …, 

定義 

starg ≪数値≫命令は,スタックから値を取り出し,それを≪数値≫番目の実引数スロットにおく(第

1章参照)。≪値≫の型は,現在実行中のメソッドの呼出し情報で指定されてた実引数の型と一致していな

ければならない。starg.s命令は,最初の256個の実引数に使用するのに効率のよい符号化形式を提供す

る。 

可変長の引数並びをとる手続については,starg命令は,最初の固定の実引数にだけ使用することがで

き,識別情報の可変の部分には使用できない。 

長さが4バイトより短い整数を保持する引数への格納を行うと,スタックから実引数に転記する時に値

が切り捨てられる。浮動小数点の値は,プラットフォーム固有の大きさ(F型)から実引数に関連付けら

れた大きさに丸められる。 

例外 

なし。 

適正性 

適正なCILは,≪数値≫が妥当な実引数スロットであることを要求する。 

正当性検証可能性 

background image

353 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

正当性検証は,≪値≫の正当性検証の型が,現在実行中のメソッドの識別情報で指定された実引数の型

と一致することも検査する(正当性検証の型はCLIの型と比較して詳細化されていない。)。 

3.62 stind.<type> − スタックから間接的に値を格納する 

形式 

アセンブリ形式 

定義 

52 

stind.i1 

int8型の値をアドレスのメモリに格納する。 

53 

stind.i2 

int16型の値をアドレスのメモリに格納する。 

54 

stind.i4 

int32型の値をアドレスのメモリに格納する。 

55 

stind.i8 

int64型の値をアドレスのメモリに格納する。 

56 

stind.r4 

float32型の値をアドレスのメモリに格納する。 

57 

stind.r8 

float64型の値をアドレスのメモリに格納する。 

DF 

stind.i 

native int型の値をアドレスのメモリに格納する。 

51 

stind.ref 

オブジェクト参照(O型)の値をアドレスのメモリに格納する。 

スタック推移 

…, ≪アドレス≫, ≪値≫ ◊ … 

定義 

stind命令は,値≪値≫を,アドレス≪アドレス≫(管理外ポインタ,native int型又は管理下ポイ

ンタ,&型。)に格納する。≪アドレス≫で指定されたアドレスは,≪値≫の自然な大きさに境界調整され

ていなければならない。そうでなければ,NullReferenceExceptionが送出される可能性がある(ただ

し,unaligned.接頭辞命令が指定されている場合を除く。unaligned.接頭辞命令を参照する。)。アド

レスを返すすべてのCIL命令(例えばldloca及びldarga。)の結果は,安全に境界調整されている。1

バイトより大きなデータ型については,バイト順序は対象のCPUに依存する。バイト順序に依存するコー

ドは,すべてのプラットフォーム上で動作するとは限らない。すべてのstind命令は,対応する組込み型

の値クラスを指定するstobj命令への短絡形式になっている。 

型安全な操作であるためには,stind命令が,ポインタ型と矛盾しない方法で使われていなければなら

ない。 

stind命令の動作は,直前に先行するvolatile.又はunaligned.接頭辞命令によって変更できる。 

例外 

≪アドレス≫が,命令の接尾辞で示された実引数の型に対して,自然な境界に調整されていない場合,

System.NullReferenceExceptionを送出する。 

適正性 

適正なCILは,1.6に規定した暗黙の変換を前提として,≪アドレス≫が≪値≫の型と代入互換性のあ

る型のポインタであることを保証する。 

正当性検証可能性 

正当性検証可能なコードについては,≪アドレス≫は管理下ポインタでなければならない。また,≪値

≫の型は代入互換性のある型でなければならない。すなわち,1.8.1.2.2の規則に従い,≪アドレス≫がS&

型で,≪値≫の型がT型である場合,S := Tでなければならない。 

3.63 stloc − スタックから値を取り出し,局所変数に格納する 

形式 

アセンブリ形式 

定義 

FE 0E <unsigned 
int16> 

stloc ≪添字≫ 

スタックから値を取り出し,局所変数≪添字≫に格納する。 

13 <unsigned int8> stloc.s ≪添字≫ スタックから値を取り出し,局所変数≪添字≫に格納する。短縮

形式。 

background image

354 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

0A 

stloc.0 

スタックから値を取り出し,局所変数0に格納する。 

0B 

stloc.1 

スタックから値を取り出し,局所変数1に格納する。 

0C 

stloc.2 

スタックから値を取り出し,局所変数2に格納する。 

0D 

stloc.3 

スタックから値を取り出し,局所変数3に格納する。 

スタック推移 

…, ≪値≫ ◊ … 

定義 

stloc ≪添字≫命令は,評価スタックから最上部の値を取り出し,局所変数番号≪添字≫に格納する(第

1章参照)。ここで,局所変数は0から増加方向に付番する。≪値≫の型は,現在実行中のメソッドの局所

識別情報で指定された局所変数の型と一致しなければならない。stloc.0,stloc.1,stloc.2及び

stloc.3命令は,最初の4個の局所変数に対して効率的な符号化を提供する。stloc.s命令は,局所変

数4〜255のために効率的な符号化を提供する。 

長さが4バイトより短い整数を保持する局所変数への格納を行うと,スタックから局所変数に値を移す

時に,値が切り捨てられる。浮動小数点の値は,プラットフォーム固有の大きさ(F型)から実引数に関

連付けられた型に丸められる。 

例外 

なし。 

適正性 

適正なCILは,≪添字≫が妥当な局所添字であることを要求する。stloc ≪添字≫命令については,

≪添字≫は両端を含んで0〜65534の範囲になければならない(65535は妥当ではない。)。 

注記 (根拠)65535を除外するのは,実践的な理由による。ありそうな実装は,指定されたメソッ

ドに対する局所変数の添字及び局所変数の総数の両方の追跡のために,2バイト整数を使用す

るだろう。添字65535を妥当とした場合,指定されたメソッド内の局所変数の個数を追跡する

ために,より大きな整数が必要になっていただろう。 

正当性検証可能性 

正当性検証は,≪値≫の正当性検証の型が,現在実行中のメソッドの局所変数の識別情報で指定された

型と一致していることも検査する。 

3.64 sub − 数値を減算する 

形式 

アセンブリ形式 

定義 

59 

sub 

≪値1≫から≪値2≫を減算し,新しい値を返す。 

スタック推移 

…, ≪値1≫, ≪値2≫ ◊ …, ≪結果≫ 

定義 

sub命令は,≪値1≫から≪値2≫を減算し,結果をスタックに入れる。整数演算については,オーバ

フローは検出されない(sub.ovf参照)。浮動小数点の演算対象については,subは,正のオーバフロー

である場合+inf,負のオーバフローである場合-inf,浮動小数点のアンダフローである場合ゼロを返す。 

受理可能な演算対象の型及び対応する結果のデータ型については,表2 2項数値演算にまとめてある。 

例外 

なし。 

適正性及び正当性検証可能性 

表2 2項数値演算を参照する。 

background image

355 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

3.65 sub.ovf.<type> − オーバフローの検査をしながら整数値を減算する 

形式 

アセンブリ形式 

定義 

DA 

sub.ovf 

native intからnative intを減算する。符号付きの結果
は同じ大きさに収まらなければならない。 

DB 

sub.ovf.un 

native unsigned intからnative unsigned intを減
算する。符号なしの結果は同じ大きさに収まらなければならな
い。 

スタック推移 

…, ≪値1≫, ≪値2≫ ◊ …, ≪結果≫ 

定義 

sub.ovf命令は,≪値1≫から≪値2≫を減算し,結果をスタックに入れる。値の型及び返却値の型は

命令によって指定される。結果が結果型に収まらない場合,例外を送出する。 

受理可能な演算対象の型及び対応する結果のデータ型については,表7 オーバフロー算術演算にまと

めてある。 

例外 

結果を結果の型で表現できない場合,System.OverflowExceptionを送出する。 

適正性及び正当性検証可能性 

表7 オーバフロー算術演算を参照する。 

3.66 switch − 値に基づいて表を切り替える 

形式 

アセンブリ形式 

定義 

45 <unsigned int32> 
<int32> ... <int32> 

switch (≪表1≫, ≪表
2≫ ... ≪表N≫) 

n個の値のうちの一つに飛び越す。 

スタック推移 

…, ≪値≫ ◊ …, 

定義 

switch命令は,飛越し表を実装する。命令の形式は,飛越し対象の個数Nを表すunsigned int32

型に,飛越し対象を指定するN個のint32型の値が後続する。飛越し対象は,このswitch命令の直後

の命令の先頭からの(正及び負の)オフセットとして表現される。 

switch命令は,スタックから≪値≫を取り出し,それを符号なし整数としてnと比較する。≪値≫が

n未満である場合,≪値≫番目の対象に実行を移す。ここで,対象は0から付番する(すなわち,≪値≫

が0であれば最初の対象を選択し,≪値≫が1であれば2番目の対象を選択する。以下同様。)。≪値≫が

n未満でない場合,実行は次の命令に継続する(通り抜ける。)。 

対象の命令が一つ以上の接頭辞コードをもっている場合,複数の接頭辞のうち,最初の接頭辞にだけ制

御を移すことができる。 

try,catch,filter及びfinallyブロック内への制御の移行並びにこれらのブロックの外への制御

の移行は,この命令では実行できない(このような制御の移行は,厳しく制限されており,この命令では

なくleave命令を使用しなければならない。詳細については第1章を参照する。)。 

例外 

なし。 

適正性 

適正なCILは,上に示した制御移行の制約に従う。詳細については1.5を参照する。 

background image

356 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

正当性検証可能性 

正当性検証は,スタック,局所,及び考えられるすべての経路に対して,制御移行先の命令の実引数の

型一貫性を要求する。詳細については1.8を参照する。 

3.67 xor − ビット単位のXORを計算する 

形式 

アセンブリ形式 

定義 

61 

xor 

整数値のビット単位のXORをとり,整数を返す。 

スタック推移 

..., ≪値1≫, ≪値2≫ ◊ ..., ≪結果≫ 

定義 

xor命令は,≪値1≫と≪値2≫とのビット単位のXORを計算し,結果をスタックに入れる。 

受理可能な演算対象の型及び対応する結果のデータ型については,表5 整数演算にまとめてある。 

例外 

なし。 

適正性及び正当性検証可能性 

表5 整数演算を参照する。 

オブジェクトモデル命令 

基本命令集合に記述した命令は,実行されているオブジェクトモデルに依存しない。それらの命令は,

実際のCPUに見られる命令に密接に対応する。オブジェクトモデル命令は,それらが複数の基本命令及び

基盤になるオペレーティングシステムの呼出しから構築されるという意味で,基本命令と比較して組込み

命令的ではない。 

注記 (根拠)オブジェクトモデル命令は,多くの(しかし決してすべてではない。)より高級な言語

が利用するサービスの集合の共通の効率的な実装を提供する。オブジェクトモデル命令は,CTS

によって定義された規約の集合をオブジェクトモデル命令の中に埋め込んでいる。これには次

のものが含まれる。 

− オブジェクト内のフィールドの配置。 

− 遅延結合メソッド呼出しのための配置(vtables)。 

− メモリの割付け及び再利用。 

− 例外処理。 

− 参照を基本とするオブジェクトと値型とを変換するボックス化及びボックス化解除。 

詳細については,第1章を参照する。 

4.1 

box − ボックス化可能な値をボックス化された形式に変換する 

形式 

アセンブリ形式 

定義 

8C <T> 

box ≪型トークン≫ 

ボックス化可能な値をボックス化された形式に変換する。 

スタック推移 

…, ≪値≫ ◊ …, ≪オブジェクト≫ 

定義 

≪型トークン≫が値型である場合,box命令は≪値≫をボックス化された形式に変換する。≪型トーク

ン≫がnull許容でない型(1.8.2.4参照)である場合,ボックス化された形式への変換は,新しいオブジェ

クトを生成し,≪値≫のデータをこの新しく割り付けたオブジェクトにコピーすることによって行われる。

background image

357 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

≪型トークン≫がnull許容型である場合,ボックス化された形式への変換は,≪値≫のHasValue特性を調

べることによって行われる。HasValueが偽である場合,null参照をスタックに投入する。HasValueが偽で

なければ,≪値≫のValue特性をボックス化した結果をスタックに投入する。≪型トークン≫が参照型で

ある場合,box命令は何もしない。 

≪型トークン≫は≪値≫の型を示すメタデータトークン(typedef,typeref又はtypespec。)とす

る。≪型トークン≫は,値型,参照型又は総称仮引数を表現できる。 

例外 

要求を満たすためのメモリが不足している場合,System.OutOfMemoryExceptionを送出する。 

≪型トークン≫が見つからない場合,System.TypeLoadExceptionを送出する。これは,典型的に

はCILが実行時以外にプラットフォーム固有のコードに変換される場合に検出される。 

適正性 

≪型トークン≫は,妥当なtypedef,typeref又はtypespecメタデータトークンでなければならな

い。型演算対象≪型トークン≫はボックス化可能な型を表さなければならない。 

正当性検証可能性 

スタックの最上部の要素は,≪型トークン≫で表現された型と代入互換性のあるものになっていなけれ

ばならない。≪型トークン≫がnull許容でない型又は総称仮引数を表す場合,結果の型はボックス化した

≪型トークン≫とする。≪型トークン≫がNullable<T>である場合,結果の型はボックス化したTとする。

≪型トークン≫が参照型である場合,結果の型は≪型トークン≫とする。型演算対象≪型トークン≫は,

byref,byref-like及びvoid型であってはならない。 

注記 (根拠)上記の規則に従い,≪型トークン≫が実行時の型がNullable<T>であるような総称仮引

数を表すとき,正当性検証はボックス化したNullable<T>の型になっていることを主張する。こ

れは,ボックスの生成の実装と直接的には一致しない。実行時には,Nullable<T>型の値をボッ

クス化するというのは,正当性検証の機構が主張するように,実際にはボックス化した

Nullable<T>を生成するのではなく,ボックス化したTを生成するという意味だろう。これを型

安全にするために,正当性検証はボックス化したNullable<T>に対して,ボックス化したTに対

して許可されていない,いかなる操作も許可してはならない。この要件は,Nullable<T>が,例

えばインタフェース実装のような,いかなる制約付きの機能ももっていてはならないというこ

とを要求する。 

4.2 

callvirt − 実行時にオブジェクトに関連付けられたメソッドを呼び出す 

形式 

アセンブリ形式 

定義 

6F <T> 

callvirt ≪メソッド≫ 

オブジェクトに関連付けられたメソッドを呼び出す。 

スタック推移 

…, ≪オブジェクト≫, ≪実引数1≫, … ≪実引数N≫ ◊ …, ≪返却値≫(必ず返され

るとは限らない。) 

定義 

callvirt命令は,オブジェクト上の遅延結合メソッドを呼び出す。すなわち,≪メソッド≫メタデー

タトークン中の可視なコンパイル時のクラスではなく,≪オブジェクト≫の厳密な型に基づいてメソッド

を選択する。callvirtは仮想メソッド及びインスタンスメソッドの両方を呼び出すために使用できる。

CIL呼出し手順の詳細な定義については,第1章を参照する。callvirt命令は,制御移行前に現在のス

タックフレームを解放すべきであることを指定するために,直前にtail.接頭辞をおくことができる。呼

background image

358 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

出しが,元のメソッドより高い信頼度のメソッドに制御を移す場合,スタックフレームは解放されないだ

ろう。 

注記 “より高い信頼度”の呼出し先とは,呼出し先の権限許可集合が呼出し側の許可集合の厳密な

スーパーセットであることと定義する。 

≪メソッド≫は,呼び出されるメソッドの名前,クラス及び識別情報を提供するメタデータトークン

(methoddef,methodref又はmethodspec。第2章を参照する。)とする。より詳細には,callvirt

について次のように考えることができる。あるクラスのインスタンスである≪オブジェクト≫を考える。

≪オブジェクト≫のクラスが指示されたメソッド名及び識別情報に一致する非静的メソッドを定義してい

る場合,そのメソッドを呼び出す。そうでなければ,≪オブジェクト≫のクラスのスーパークラス連鎖中

のすべてのクラスを順番に検査する。メソッドが見つからない場合,エラーになる。 

callvirtは,メソッドを呼び出す前に評価スタックからオブジェクト及び実引数を取り出す。メソッ

ドが返却値をもっている場合,メソッド完了時に返却値をスタックに入れる。呼出し先では,≪オブジェ

クト≫仮引数は実引数0,≪実引数1≫は実引数1のようにアクセスされる。 

実引数は,左から右の順番にスタックに配置される。すなわち,最初の実引数が計算されてスタックに

おかれ,次に2番目の実引数のような順におかれる。thisポインタ(callvirtに対しては常に必要と

なる。)は,利用者に可視な実引数のどれよりも前に入れられなければならない。メタデータに入れて運ば

れた識別情報は,thisポインタに対する仮引数並び中の要素を含んでいないが,メソッドがthisポイ

ンタを渡す必要があるかどうかを示すために(HASTHISと呼ばれる)ビットを使用する(第2章参照)。 

call命令を用いて仮想メソッドを呼び出すこともできることに注意する。 

例外 

≪オブジェクト≫のクラス及びその基底クラスのいずれにも,指示された名前及び識別情報をもった非

静的メソッドが見つからない場合,System.MissingMethodExceptionを送出する。これは,典型的

には実行時以外にCILがプラットフォーム固有のコードに変換される場合に検出される。 

≪オブジェクト≫がnullである場合,System.NullReferenceExceptionを送出する。 

システムセキュリティが,呼出し側が呼び出される側のメソッドにアクセスすることを認めない場合,

System.SecurityExceptionを送出する。実行時ではなく,CILがプラットフォーム固有のコードに

変換された時点でセキュリティ検査を行う可能性がある。 

適正性 

適正なCILは,呼出し先のメソッドが存在すること及びスタック上の値が呼び出そうとしているメソッ

ドの仮引数の型と一致することを保証する。 

正当性検証可能性 

典型的な使い方では,(a)上のすべての制限が満たされ,かつ,(b)≪オブジェクト≫の正当性検証の

型が呼び出そうとしているメソッドと矛盾せず,かつ,(c)スタック上の実引数の正当性検証の型がメソ

ッドの呼出しが期待する型と矛盾せず,かつ,(d)メソッドが呼出し元からアクセス可能である場合に,

callvirtは正当性検証可能とする。tail.が付記されたcallvirtについては,追加の考慮点がある(1.8

参照)。 

4.3 

castclass − オブジェクトをクラスにキャストする 

形式 

アセンブリ形式 

定義 

74 <T> 

castclass ≪クラス≫ ≪オブジェクト≫を≪クラス≫にキャストする。 

スタック推移 

background image

359 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

…, ≪オブジェクト≫ ◊ …, ≪オブジェクト2≫ 

定義 

castclass命令は,(O型の)≪オブジェクト≫を≪クラス≫にキャストすることを試みる。≪クラス

≫は,希望のクラスを示すメタデータトークン(typeref,typedef又はtypespec。)とする。≪クラ

ス≫がSystem.Nullable<T>型で,オブジェクトのクラスがTである場合,castclassは成功する。

そうでなければ,スタックの最上部のオブジェクトのクラスが,(≪クラス≫がインタフェースである場合

については)≪クラス≫を実装していない場合,及び(≪クラス≫が通常のクラスである場合については)

≪クラス≫の派生クラスでない場合,InvalidCastExceptionを送出する。 

次の点に注意する。 

1) 配列はSystem.Arrayを継承する。 

2) FooがBarにキャスト可能な場合,Foo[] はBar[] にキャスト可能とする。 

3) 上の2)のために,列挙型はその基礎とする型として扱われる。したがって,E1及びE2が基礎とす

る型を共有している場合,E1[] はE2[] にキャストできる。 

≪オブジェクト≫がnullである場合,castclassは成功し,nullを返す。この動作はisinstとは異

なる。 

例外 

≪オブジェクト≫を≪クラス≫にキャストできない場合,System.InvalidCastExceptionを送出す

る。 

≪クラス≫が見つからない場合,System.TypeLoadExceptionを送出する。これは典型的には,CIL

が実行時以外にプラットフォーム固有のコードに変換される場合に検出される。 

適正性 

適正なCILは,≪クラス≫が妥当なトークンtyperef, typedef又はtypespecであり,≪オブジ

ェクト≫が常にnull又はオブジェクト参照であることを保証する。 

正当性検証可能性 

追加の正当性検証要件はない。 

4.4 

cpobj − あるアドレスから別のアドレスに値をコピーする 

形式 

アセンブリ形式 

定義 

70 <T> 

cpobj ≪型トークン≫ ≪コピー元≫から≪コピー先≫に値型をコピーする。 

スタック推移 

…, ≪コピー先≫, ≪コピー元≫ ◊ …, 

定義 

cpobj命令は,≪コピー元≫(管理外ポインタ,native int又は管理下ポインタ,&。)で指定され

たアドレスの値を≪コピー先≫(これもポインタ。)で指定されたアドレスにコピーする。≪型トークン≫

は,typedef,typeref又はtypespecとする。≪コピー元≫で参照される位置が≪コピー先≫で参照

される位置の型と代入互換性をもっていない場合,動作は未規定とする。 

≪型トークン≫が参照型である場合,cpobj命令はstind.refが後続するldind.refと同じ効果を

もつ。 

例外 

不当なアドレスを検出した場合,System.NullReferenceExceptionを送出する可能性がある。≪

型トークン≫が見つからない場合,System.TypeLoadExceptionを送出する。これは典型的には,CIL

background image

360 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

が実行時以外にプラットフォーム固有のコードに変換される場合に検出される。 

適正性 

≪型トークン≫は妥当なtypedef,typeref又はtypespecメタデータトークンでなければならない。 

正当性検証可能性 

≪コピー先≫の値の型と≪コピー元≫の値の静的な型は,いずれも管理下ポインタ(&)でなければな

らない。≪コピー先≫の値の静的な型と≪コピー元≫の値の静的な型を,それぞれ≪コピー先の型≫及び

≪コピー元の型≫と書くことにすると,最終的に,≪コピー元の型≫は,≪型トークン≫と代入互換性が

なければならず,≪型トークン≫は≪コピー先の型≫と代入互換性がなければならない。ここで,enum

である場合には,型はEnumの基礎とする型又は基底型とする。 

4.5 

initobj − あるアドレスの値を初期化する 

形式 

アセンブリ形式 

定義 

FE 15 <T> 

initobj ≪型トークン≫ 

アドレス≪初期化先≫の値を初期化する。 

スタック推移 

…,≪初期化先≫ ◊ …, 

定義 

initobj命令は,あるアドレスを省略時の値で初期化する。≪型トークン≫はメタデータトークン

(typedef,typeref又はtypespec。)とする。≪初期化先≫は管理外ポインタ(native int)又は

管理下ポインタ(&)とする。≪型トークン≫が値型である場合,initobj命令は≪初期化先≫の各々の

フィールドをnull又は適切な組込み型の0で初期化する。≪型トークン≫が値型である場合,この命令が

実行された後,インスタンスは構築子メソッドを呼ぶ準備が整っている。≪型トークン≫が参照型である

場合,initobj命令はstind.refが後続するldnullと同じ効果をもつ。 

newobjとは異なり,initobj命令はいかなる構築子メソッドも呼び出さない。 

例外 

なし。 

適正性 

≪型トークン≫は妥当なtypedef,typeref又はtypespecメタデータトークンでなければならない。 

正当性検証可能性 

スタックの最上部にある初期化先の値の型は,≪初期化先の型≫の型への管理下ポインタでなければな

らない。また,≪型トークン≫は≪初期化先の型≫の部分型でなければならない。≪型トークン≫が参照

型でない場合,この部分型についての規定は,≪初期化先の型≫と≪型トークン≫が同じであることを意

味する。 

4.6 

isinst − オブジェクトがクラスかインタフェースのインスタンスかどうか試験する 

形式 

アセンブリ形式 

定義 

75 <T> 

isinst ≪クラス≫ 

≪オブジェクト≫が≪クラス≫のインスタンスであるかどうか検査し,
null又はそのクラス若しくはインタフェースのインスタンスを返す。 

スタック推移 

…, ≪オブジェクト≫ ◊ …, ≪結果≫ 

定義 

isinst命令は,(O型の)≪オブジェクト≫が≪クラス≫のインスタンスかどうか検査する。≪クラス

≫は,所望のクラスを示すメタデータトークン(typeref,typedef又はtypespec,第2章参照)とする。

background image

361 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

スタックの最上部のオブジェクトのクラスが≪クラス≫を実装している場合(≪クラス≫がインタフェー

スである場合。),≪クラス≫の派生クラスである場合(≪クラス≫が通常のクラスである場合。),又は,

≪クラス≫がSystem.Nullable<T>であり,かつ,オブジェクトのクラスがT型である場合,castclass

が呼び出されたのと厳密に同じように,それを≪クラス≫型にキャストし,結果をスタックに入れる。そ

うでなければ,スタックにnullを入れる。≪オブジェクト≫がnullである場合,isinstはnullを返す。 

次の点に注意する。 

1) 配列はSystem.Arrayを継承する。 

2) FooがBarにキャスト可能な場合,Foo[]はBar[]にキャスト可能とする。 

3) 注意事項2のために,列挙型はその基礎とする型として扱われる。したがって,E1とE2とが基礎

とする型を共有している場合,E1[]はE2[]にキャスト可能とする。 

例外 

≪クラス≫が見つからない場合,System.TypeLoadExceptionを送出する。これは典型的には,CIL

が実行時以外にプラットフォーム固有コードに変換される場合に検出される。 

適正性 

適正なCILは,≪クラス≫がクラスを示す妥当なtyperef,typedef又はtypespecトークンである

こと及び≪オブジェクト≫が常にnull又はオブジェクト参照のいずれかになっていることを保証する。 

正当性検証可能性 

追加の正当性検証要件はない。 

4.7 

ldelem − 配列から要素をロードする 

形式 

アセンブリ形式 

定義 

A3 <T> 

ldelem ≪型トークン≫ ≪添字≫の位置にある要素をスタックの最上部にロードする。 

スタック推移 

…, ≪配列≫, ≪添字≫ ◊ …, ≪値≫ 

定義 

ldelem命令は,添字≪添字≫(native int又はint32型)を使って,0から始まる1次元配列≪配

列≫の中の要素の値をロードし,その値をスタックの最上部に入れる。返却値の型は命令中の≪型トーク

ン≫によって示される。 

例外 

≪添字≫が≪配列≫の範囲より大きい場合,System.IndexOutOfRangeExceptionを送出する。 

配列が空である場合,System.NullReferenceExceptionを送出する。 

適正性 

≪型トークン≫は,妥当なtypedef,typeref又はtypespecメタデータトークンでなければならな

い。 

≪配列≫は,null又は1次元の0から始まる配列でなければならない。 

正当性検証可能性 

≪配列≫の静的な型は,特殊な参照型であるNull又は適切な0から始まる1次元配列型elem[]のい

ずれかでなければならない。ここでelemは何らかの型とする。配列型がNullである場合,elemは演算対

象≪型トークン≫によって表される型とする。≪添字≫の値はnative int型でなければならない。型

elemは≪型トークン≫型の部分型でなければならない。スタック上の左側にある値の型は≪型トークン

background image

362 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

≫とする。 

4.8 

ldelem.<type> − 配列の要素をロードする 

形式 

アセンブリ形式 

定義 

90 

ldelem.i1 

スタックの最上部の,≪添字≫番目のint8型の要素をint32とし
てロードする。 

92 

ldelem.i2 

スタックの最上部の,≪添字≫番目のint16型の要素をint32とし
てロードする。 

94 

ldelem.i4 

スタックの最上部の,≪添字≫番目のint32型の要素をint32とし
てロードする。 

96 

ldelem.i8 

スタックの最上部の,≪添字≫番目のint64型の要素をint64とし
てロードする。 

91  

ldelem.u1 

スタックの最上部の,≪添字≫番目のunsigned int8型の要素を
int32としてロードする。 

93 

ldelem.u2 

スタックの最上部の,≪添字≫番目のunsigned int16型の要素を
int32としてロードする。 

95 

ldelem.u4 

スタックの最上部の,≪添字≫番目のunsigned int32型の要素を
int32としてロードする。 

96 

ldelem.u8 

スタックの最上部の,≪添字≫番目のunsigned int64型の要素を
int64としてロードする。 

98 

ldelem.r4 

スタックの最上部の,≪添字≫番目のfloat32型の要素をFとして
ロードする。 

99 

ldelem.r8 

スタックの最上部の,≪添字≫番目のfloat64型の要素をFとして
ロードする。 

97 

ldelem.i 

スタックの最上部の,≪添字≫番目のnative int型の要素を
native intとしてロードする。 

9A 

ldelem.ref 

スタックの最上部の,≪添字≫番目のオブジェクト型の要素をOと
してロードする。Oの型はCILスタックに投入されている配列の要
素型と同じ型とする。 

スタック推移 

…, ≪配列≫, ≪添字≫ ◊ …, ≪値≫ 

定義 

ldelem命令は,添字が0から始まる1次元配列≪配列≫中の,添字(int32型又はnative int型

の)≪添字≫の要素の値をロードし,それをスタックの最上部に入れる。配列はオブジェクトであり,し

たがってO型の値によって表現される。返却値は命令によって指定される。 

添字が0から始まらない1次元配列及び多次元配列に対しては,配列クラスがGetメソッドを提供する。 

4バイト未満の整数値は,評価スタックにロードされる時に(native intではなく)int32に拡張さ

れることに注意する。浮動小数点数値は,評価スタックにロードされる時に,F型に変換される。 

例外 

≪配列≫がnullである場合,System.NullReferenceExceptionを送出する。 

≪添字≫が負又は≪配列≫の境界より大きい場合,System.IndexOutOfRangeExceptionを送出す

る。 

適正性 

適正なCILは,≪配列≫がnull,又は,宣言された要素型が指定された命令の接尾辞の型と厳密に一致

する添字が0から始まる1次元の配列であることを保証する(例えば,ldelem.r4が適用できるのは,

background image

363 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

要素がfloat32で添字が0から始まる1次元配列だけとする。)。 

正当性検証可能性 

≪添字≫の型はint32又はnative intでなければならない。≪配列≫の要素型は,上に示した接尾

辞で指定した型と一致しなければならない。 

4.9 

ldelema − 配列の要素のアドレスをロードする 

書式 

アセンブリ書式 

定義 

8F <T> 

ldelema ≪クラス≫ ≪添字≫番目の要素のアドレスをスタックの最上部にロードする。 

スタック推移 

…, ≪配列≫, ≪添字≫ ◊ …, ≪アドレス≫ 

定義 

ldelema命令は,(要素型が≪クラス≫の)添字が0から始まる1次元配列中の添字(int32又は

native int型の)≪添字≫の要素のアドレスをロードして,スタックの最上部に入れる。配列はオブジ

ェクトであるため,O型の値によって表現される。返却するアドレスは,管理下ポインタ(&型)とする。 

添字が0から始まらない1次元配列及び多次元配列に対しては,配列クラスがAddressメソッドを提

供する。 

この命令にreadonly.接頭辞がついている場合,制御された変更可能な管理下ポインタを生成する

(1.8.1.2.2参照)。 

例外 

≪配列≫がnullである場合,System.NullReferenceExceptionを送出する。 

≪添字≫が負又は≪配列≫の境界より大きい場合,System.IndexOutOfRangeExceptionを送出す

る。 

≪配列≫が要求された型の要素を保持していない場合,System.ArrayTypeMismatchExceptionを

送出する。 

適正性 

適正なCILは,≪クラス≫がクラスに対するトークンtyperef,typedef又はtypespecであること,

及び≪配列≫が本当に常にnullか宣言された要素型が厳密に≪クラス≫と一致する添字が0から始まる1

次元配列になっていることを保証する。 

正当性検証可能性 

≪添字≫の型は,int32又はnative intでなければならない。≪配列≫の要素型は≪クラス≫と厳

密に一致しなければならない。 

4.10 ldfld − オブジェクトのフィールドをロードする 

形式 

アセンブリ形式 

定義 

7B <T> 

ldfld ≪フィールド≫ オブジェクト(又は値型)≪オブジェクト≫の≪フィールド≫の値を

スタックに入れる。 

スタック推移 

…, ≪オブジェクト≫ ◊ …, ≪値≫ 

定義 

ldfld命令は,≪オブジェクト≫のフィールドの値をスタックに入れる。≪オブジェクト≫は,オブジ

ェクト(O型),管理下ポインタ(&型),管理外ポインタ(native int型)又は値型のインスタンスで

なければならない。正当性検証可能なコードの中では,管理外ポインタの使用は認められない。≪フィー

background image

364 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

ルド≫は,メタデータトークン(fieldref又はfielddef,第2章参照)とし,それはフィールドメン

バを参照しなければならない。返却値の型は≪フィールド≫に関連付けられた型とする。ldfldは,スタ

ックからオブジェクト参照を取り出し,その位置にfieldの値を入れる。フィールドは,インスタンスフ

ィールド(その場合,≪オブジェクト≫はnullであってはならない。)又は静的フィールドのいずれでも

よい。 

unaligned.及びvolatile.接頭辞のいずれか又は両方が,ldfld命令の前に先行できる。 

例外 

≪オブジェクト≫がnullで,フィールドが静的でない場合,System.NullReferenceExceptionを

送出する。 

メタデータの中に≪フィールド≫が見つからない場合,System.MissingFieldExceptionを送出す

る。これは典型的には,CILが実行時以外にプラットフォーム固有のコードに変換される場合に検出され

る。 

≪オブジェクト≫がnullでフィールドが静的でない場合,System.NullReferenceExceptionを送

出する。 

適正性 

適正なCILは,≪フィールド≫がフィールドを参照する妥当なトークンであること,及び≪オブジェク

ト≫が常に検索が行われている間に要求されるものと互換性のある型になっていることを保証する。 

正当性検証可能性 

正当性検証可能なコードについては,≪オブジェクト≫は管理外ポインタであってはならない。 

重なったオブジェクト参照フィールドにアクセスすることは正当性検証可能ではない。 

フィールドは,そのフィールドと重なりあっているすべてのフィールドがアクセス可能な場合に限り,

アクセス可能とする。 

4.11 ldflda − フィールドのアドレスをロードする 

形式 

アセンブリ形式 

定義 

7C <T> 

ldflda ≪フィール
ド≫ 

オブジェクト≪オブジェクト≫の≪フィールド≫のアドレスをスタ
ックに入れる。 

スタック推移 

…, ≪オブジェクト≫ ◊ …, ≪アドレス≫ 

定義 

ldflda命令は,≪オブジェクト≫のフィールドのアドレスをスタックに入れる。≪オブジェクト≫は,

オブジェクト(O型),管理下ポインタ(&型)又は管理外ポインタ(native int型)のいずれかとする。

正当性検証可能なコード中では,管理下ポインタの使用は認められない。ldfldaの返す値は,≪オブジ

ェクト≫が管理外ポインタでない場合は,管理下ポインタ(&型)とする。≪オブジェクト≫が管理外ポ

インタである場合は,ldfldaの返す値は,管理外ポインタ(native int型)とする。 

≪フィールド≫は,メタデータトークン(fieldref又はfielddef,第2章参照)とし,それはフィ

ールドメンバを参照していなければならない。フィールドは,インスタンスフィールド(その場合,≪オ

ブジェクト≫はnullであってはならない。)又は静的フィールドのいずれでもよい。 

例外 

≪フィールド≫がアクセス可能でない場合,System.FieldAccessExceptionを送出する。 

≪オブジェクト≫にアクセスしようとしているアプリケーション領域の範囲内に≪オブジェクト≫がな

background image

365 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

い場合,System.InvalidOperationExceptionを送出する。アクセス中のアプリケーション領域の内

部にないフィールドのアドレスはロードできない。 

≪フィールド≫がメタデータ中に見つからない場合,System.MissingFieldExceptionを送出する。

これは典型的には,CILが実行時以外にプラットフォーム固有のコードに変換される場合に検出される。 

≪オブジェクト≫がnullで,フィールドが静的でない場合,System.NullReferenceExceptionを

送出する。 

適正性 

適正なCILは,≪フィールド≫が妥当なfieldrefトークンであることを保証する。また,検索が行わ

れている間,≪オブジェクト≫が常に要求された型と互換性のある型になっていることを保証する。 

正当性検証可能性 

正当性検証可能なコードでは,≪フィールド≫が初期化専用であってはならない。 

重なったオブジェクト参照フィールドにアクセスすることは正当性検証可能ではない。 

フィールドは,そのフィールドと重なりあっているすべてのフィールドがアクセス可能な場合に限り,

アクセス可能とする。 

注記 静的な初期化専用フィールドのアドレスを算出するためにldfldaを使用し,その結果得られ

たポインタを用いて,クラス初期化子の本体の外側でその値を変更すると,予測不可能な動作

になるかもしれない。 

4.12 ldlen − 配列の長さをロードする 

形式 

アセンブリ形式 

定義 

8E 

ldlen 

配列の長さを(native unsigned int型で)スタックに入れる。 

スタック推移 

…, ≪配列≫ ◊ …, ≪長さ≫ 

定義 

ldlen命令は,(添字が0から始まる1次元の配列。)≪配列≫の要素の個数をスタックに入れる。 

配列はオブジェクトとするため,O型の値によって表現される。返却値はnative unsigned intと

する。 

例外 

≪配列≫がnullである場合,System.NullReferenceExceptionを送出する。 

適正性 

適正なCILは,≪配列≫が本当に常にnull又は添字が0から始まる1次元配列であることを保証する。 

正当性検証可能性 

4.13 ldobj − 値をアドレスからスタックにコピーする 

形式 

アセンブリ形式 

定義 

71 <T> 

ldobj ≪型トークン≫ 

アドレス≪コピー元≫に格納されている値をスタックにコピーする。 

スタック推移 

…, ≪コピー元≫ ◊ …, ≪値≫ 

定義 

ldobj命令は値を評価スタックにコピーする。≪型トークン≫はメタデータトークン(typedef,

typeref又はtypespec)とする。≪コピー元≫は管理外ポインタ(native int型)又は管理下ポイ

ンタ(&)とする。≪型トークン≫が参照型である場合,ldobj命令はldind.refと同じ効果をもつ。 

background image

366 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

注記 (根拠)ldobj命令は仮引数として値型を渡すために使用することができる。 

ldobj命令の動作は,直前に先行するvolatile.又はunaligned.接頭辞命令によって変更できる。 

例外 

不当なアドレスを検出した場合,System.NullReferenceExceptionを送出する。 

≪型トークン≫が見つからない場合,System.TypeLoadExceptionを送出する。これは典型的には,

CILが実行時以外にプラットフォーム固有のコードに変換される場合に検出される。 

適正性 

≪型トークン≫は,妥当なtypedef,typeref又はtypespecメタデータトークンでなければならな

い。 

正当性検証可能性 

スタックの最上部にあるコピー元の値の静的な型は,何らかの型≪コピー元の型≫への管理下ポインタ

でなければならない。また,≪コピー元の型≫は≪型トークン≫の部分型でなければならない。スタック

に残る値の静的な型は≪型トークン≫でなければならない。 

4.14 ldsfld − クラスの静的フィールドをロードする 

形式 

アセンブリ形式 

定義 

7E <T> 

ldsfld ≪フィールド≫ ≪フィールド≫の値をスタックに入れる。 

スタック推移 

…, ◊ …, ≪値≫ 

定義 

ldsfld命令は,静的(あるクラスのすべてのインスタンスが共有する。)フィールドの値をスタックに

入れる。≪フィールド≫は静的フィールドメンバを参照するメタデータトークン(fieldref又は

fielddef,第2章参照)とする。返却値の型は≪フィールド≫に関連付けられる。 

ldsfld命令はvolatile.接頭辞をもつことができる。 

例外 

≪フィールド≫にアクセスできない場合,System.FieldAccessExceptionを送出する。 

メタデータ中に≪フィールド≫が見つからない場合,System.MissingFieldExceptionを送出する。 

適正性 

適正なCILは,≪フィールド≫が静的フィールドメンバを参照する妥当なメタデータトークンであるこ

とを保証する。 

正当性検証可能性 

追加の正当性検証要件はない。 

4.15 ldsflda − 静的フィールドのアドレスをロードする 

形式 

アセンブリ形式 

定義 

7F <T> 

ldsflda ≪フィール
ド≫ 

静的フィールド≪フィールド≫のアドレスをスタックに入れる。 

スタック推移 

…, ◊ …, ≪アドレス≫ 

定義 

ldsflda命令は,静的フィールドのアドレス(≪フィールド≫が管理下のメモリに格納されている型を

参照している場合,管理下ポインタである&型,そうでなければ管理外ポインタであるnative int。)を

background image

367 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

スタックに入れる。≪フィールド≫は,静的フィールドメンバを参照するメタデータトークン(fieldref

又はfielddef,第2章参照)とする[≪フィールド≫が代入済みのRVAをもった静的大域変数である可

能性があることに注意する。その場合,そのメモリ領域は管理外とする。ここで,RVAとは相対仮想アド

レス(Relative Virtual Address)の意味であり,フィールドを含んでいるPEファイルがメモリに読み込まれ

ている位置の基底アドレスからそのフィールドへのオフセットの意味とする。]。 

例外 

≪フィールド≫にアクセスできない場合,System.FieldAccessExceptionを送出する。 

メタデータ中に≪フィールド≫が見つからない場合,System.MissingFieldExceptionを送出する。

これは典型的には,CILが実行時以外にプラットフォーム固有のコードに変換される場合に検出される。 

適正性 

≪フィールド≫がメモリ領域が管理されている型を参照している場合,適正なCILは,≪フィールド≫

が静的フィールドメンバを参照する妥当なメタデータトークンであることを保証する。 

正当性検証可能性 

正当性検証可能なコードでは,≪フィールド≫は初期化専用であってはならない。 

注記 ldfldaを用いて静的な初期化専用フィールドのアドレスを算出し,その結果得られたポイン

タを用いて,クラス初期化子の本体の外側でその値を変更すると,予測不可能な動作になる可

能性がある。 

4.16 ldstr − リテラル文字列をロードする 

形式 

アセンブリ形式 

定義 

72 <T> 

ldstr ≪文字列≫ 

リテラル文字列について,文字列オブジェクトをスタックに入れる。 

スタック推移 

…, ◊ …, ≪文字列≫ 

定義 

ldstr命令は,文字列リテラル≪文字列≫としてメタデータ中に格納されているリテラルを表現する新

しい文字列オブジェクトをスタックに入れる。 

既定では,CLIは,同じ文字の列をもつ二つのメタデータトークンを参照する二つのldstr命令の結果

が,正確に同一の文字列オブジェクトを返すことを保証する[この処理は“文字列の強制収容(string 

interning)”として知られている。]。この動作は 

System.Runtime.CompilerServices.CompilationRelaxationAttribute及び 

System.Runtime.CompilerServices.CompilationRelaxations.NoStringInterningを使う

ことで制御できる(第4章参照)。 

例外 

なし。 

適正性 

適正なCILは,≪文字列≫が妥当な文字列リテラルのメタデータトークンであることを保証する。 

正当性検証可能性 

追加の正当性検証要件はない。 

4.17 ldtoken − メタデータトークンの実行時表現をロードする 

形式 

アセンブリ形式 

定義 

D0 <T> 

ldtoken ≪トークン≫ メタデータ≪トークン≫をその実行時表現に変換する。 

background image

368 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

スタック推移 

… ◊ …, ≪実行時ハンドル≫ 

定義 

ldtoken命令は,指定されたメタデータトークンの≪実行時ハンドル≫をスタックに入れる。トークン

は次のもののうちのいずれかでなければならない。 

methoddef,methodref又はmethodspec。この場合,RuntimeMethodHandleをスタックに入れ

る。 

typedef,typeref又はtypespec。この場合,RuntimeTypeHandleをスタックに入れる。 

fielddef又はfieldref。この場合,RuntimeFieldHandleをスタックに入れる。 

スタックに入れられた値は,システムクラスライブラリ中の自己反映メソッドの呼出しの中で使用する

ことができる。 

例外 

なし。 

適正性 

適正なCILは,≪トークン≫は上に挙げた種類の妥当なメタデータトークンを指定していなければなら

ない。 

正当性検証可能性 

追加の正当性検証要件はない。 

4.18 ldvirtftn − 仮想メソッドポインタをロードする 

形式 

アセンブリ形式 

定義 

FE 07 <T> 

ldvirtftn ≪メソッド≫ 仮想メソッド≪メソッド≫のアドレスをスタックに入れる。 

スタック推移 

… ≪オブジェクト≫ ◊ …, ≪関数≫ 

定義 

ldvirtftn命令は,≪オブジェクト≫と関連付けられ,メソッド参照≪メソッド≫(メタデータトー

クンmethoddef,methodref又はmethodspec,第2章参照)で記述される仮想メソッドを実装する

プラットフォーム固有のコードへの管理外ポインタ(native int型)をスタックに入れる。スタックに

入れられた値は,それが管理下メソッド(又は管理下コードから管理外コードに遷移するスタブ。)を参照

している場合,calli命令を用いて呼び出すことができる。 

返却された値は,≪メソッド≫で指定した呼出し規約を使用するプラットフォーム固有のコードを指す。

したがって,ルーチンが対応する呼出し規約を期待している場合,メソッドポインタを管理外のプラット

フォーム固有のコード(例えばコールバックルーチン。)に渡すことができる。この命令によって算出され

たアドレスが,この目的(例えばプラットフォーム固有の版が使用できない場合にCLIに再入すること)

のために特別に作成された仲介コードへのポインタであってもよいことに注意する。 

例外 

≪オブジェクト≫がnullである場合,System.NullReferenceExceptionを送出する。 

適正性 

適正なCILは,≪メソッド≫が妥当なトークンmethoddef,methodref又はmethodspecであるこ

とを保証する。また,その≪メソッド≫が≪オブジェクト≫に対して定義された非静的なメソッドを参照

することを保証する。 

background image

369 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

正当性検証可能性 

正当性検証は,それがメソッドポインタであることを記憶して,スタックに入れられた値の型をnative 

int型より詳細に追跡する。そのようなメソッドポインタは,正当性検証されたコードの中でcalliを

使って使用したり,委譲を構築するために使用したりすることができる。 

4.19 mkrefany -型の参照をスタックに登録する 

形式 

アセンブリ形式 

定義 

C6 <T> 

mkrefany ≪クラス≫ 

≪クラス≫型の≪ポインタ≫への参照をスタックに登録する。 

スタック推移 

…, ≪ポインタ≫ ◊ …, ≪型付けされた参照≫ 

定義 

mkrefany命令は,動的な型の参照を渡すことができる。≪ポインタ≫は,一片のデータのアドレスを

保持するポインタ(&型,又はnative int型。)でなければならない。≪クラス≫は,≪ポインタ≫の

型について記述するクラストークン(typeref又はtypedef,第2章参照)とする。mkrefanyは,≪

ポインタ≫及び≪クラス≫の非透過な記述子である型の参照をスタックに入れる。スタック上の型付けさ

れた参照に対する唯一の妥当な操作は,型付けされた仮引数として型の参照を必要とするメソッドに,そ

れを渡す。その後,呼ばれたメソッドは,型(≪クラス≫)及びアドレス(≪ポインタ≫)を取り出すた

めに,refanytype命令及びrefanyval命令をそれぞれ使用することができる。 

例外 

≪クラス≫が見つからない場合,System.TypeLoadExceptionを送出する。この例外は,典型的に

は,実行時ではなく,CILがプラットフォーム固有のコードに変換される時に,検出される。 

適正性 

適正なCILは,≪クラス≫がある型について記述する妥当なトークンtyperef又はtypedefであり,

≪ポインタ≫が厳密にその型を指すポインタであることを保証する。 

正当性検証可能性 

正当性検証では,上記に加えて,≪ポインタ≫が管理下ポインタであることを要求する。≪ポインタ≫

が≪クラス≫のインスタンスへのポインタであることを結論付けることができなければ,検証は失敗する。 

4.20 newarr − 添字が0から始まる1次元配列を生成する 

形式 

アセンブリ形式 

定義 

8D<T> 

newarr ≪要素型≫ 

≪要素型≫型の要素をもつ新しい配列を生成する。 

スタック推移 

…, ≪要素数≫ ◊ …, ≪配列≫ 

定義 

newarr命令は,要素が≪要素型≫型の,添字が0から始まる新しい1次元配列を作成する。≪要素型

≫はメタデータトークン(typeref又はtypedef,第2章参照)とする。≪要素数≫(native int型)

は,配列中の要素の個数を指定する。有効な配列の添字は,0以上≪要素数≫未満とする。値型も含めて

任意の型を配列の要素とすることができる。 

添字が0から始まる1次元配列は,適切な値型(System.Int32など)を示すメタデータトークンを用

いて生成することができる。配列の各要素は適切な型の0で初期化される。 

添字が0以外から始まる1次元配列及び多次元配列は,newarrではなくnewobjを用いて生成する。

より一般的にいえば,それらは基底フレームワークの中にあるSystem.Arrayクラスのメソッドを用い

background image

370 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

て生成される。 

例外 

要求を満たす十分なメモリが確保できない場合,System.OutOfMemoryExceptionを送出する。 

≪要素数≫が0未満である場合,System.OverflowExceptionを送出する。 

適正性 

適正なCILは,≪要素型≫が妥当なtyperef又はtypedefトークンであることを保証する。 

正当性検証可能性 

≪要素数≫はnative int型又はint32型でなければならない。 

4.21 newobj − 新規にオブジェクトを生成する 

形式 

アセンブリ形式 

定義 

73 <T> 

newobj ≪構築子≫ 

初期化されていないオブジェクト又は値型を割り付けて,≪構築子≫
を呼び出す。 

スタック推移 

…, ≪引数1≫, … ≪引数N≫ ◊ …, ≪オブジェクト≫ 

定義 

newobj命令は新しいオブジェクト又は値型の新しいインスタンスを生成する。≪構築子≫は,呼び出

そうとしている構築子の名前,クラス及び識別情報を示すメタデータトークン(構築子として印付けされ

たmethodref又はmethodef,第2章を参照する。)とする。指定された名前,クラス及び識別情報に正

確に一致する構築子が見つからない場合,MissingMethodExceptionを送出する。 

newobj命令は,≪構築子≫に関連したクラスの新しいインスタンスを割り付けて,(適切な型の)0又

はnullで,インスタンス中のすべてのフィールドを適切に初期化する。その後,この命令は,新たに生成

したインスタンスとともに与えられた実引数を渡して構築子を呼び出す。構築子を呼び出した後,初期化

済みのオブジェクト参照をスタックに登録する。 

構築子の視点から見ると,未初期化のオブジェクトが実引数0になり,その後ろにnewobjに渡された

他の実引数が順番に続く。 

添字が0から始まる1次元配列は,いずれもnewobjではなくnewarrを用いて生成される。また,他

のすべての配列(1次元を超える配列又は1次元配列だが添字が0から始まらない配列。)はnewobjを用

いて生成される。 

値型の生成では通常newobjを使用しない。値型では,通常,実引数又は局所変数として割り付けられ

るか,(添字が0から始まる1次元配列のための)newarrを使用するか,又はオブジェクトのフィールド

として割り付けられる。割り付けられた後,それらはinitobjを用いて初期化される。しかし,newobj命令

は,スタック上で値型の新しいインスタンスを生成するために使用することができる(その後,それは局

所などに格納されて,実引数として渡すことができる。)。 

例外 

≪構築子≫のクラスが抽象である場合,System.InvalidOperationExceptionを送出する。 

要求を満たす十分なメモリが確保できない場合,System.OutOfMemoryException送出する。 

指定された名前,クラス及び識別情報をもった構築子メソッドが見つからない場合,

System.MissingMethodExceptionを送出する。これは典型的には,CILが実行時以外にプラットフ

ォーム固有のコードに変換される場合に検出される。 

適正性 

background image

371 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

適正なCILは,≪構築子≫が妥当なトークンmethodref又はmethoddefであり,スタックに格納さ

れている実引数が構築子の期待する引数と互換性があることを保証する。 

正当性検証可能性 

正当性検証の過程では,委譲構築子を特別な場合とみなし,2番目の実引数として渡されたnative int

型のメソッドポインタを検査し,本当に正しい型のメソッドを参照しているか検査する。 

4.22 refanytype -型の参照からの型をロードする 

形式 

アセンブリ形式 

定義 

FE 1D 

refanytype 

型付けされた参照に格納されている型のトークンをスタックに入れる。 

スタック推移 

…, ≪型付けされた参照≫ ◊ …, ≪型≫ 

定義 

≪型付けされた参照≫に埋め込まれている型のトークンを取り出す。mkrefany命令を参照する。 

例外 

なし。 

適正性 

適正なCILは,≪型付けされた参照≫が妥当な(以前に呼び出したmkrefanyによって生成された。)

型付けされた参照であることを保証する。 

正当性検証可能性 

refanytype命令は常に正当性検証可能とする。 

4.23 refanyval − 型の参照からアドレスをロードする 

形式 

アセンブリ形式 

定義 

C2<T> 

refanyval ≪型≫ 

型の参照に格納されたアドレスをスタックに登録する。 

スタック推移 

…, ≪型付けされた参照≫ ◊ …, ≪アドレス≫ 

定義 

≪型付けされた参照≫に埋め込まれている(&型の)アドレスを取り出す。≪型付けされた参照≫の中

の参照の型は,≪型≫(typedef又はtyperefのいずれかのメタデータトークン,第2章を参照する。)

によって指定された型に一致しなければならない。mkrefany命令を参照する。 

例外 

≪型≫が≪型付けされた参照≫に格納されている型(すなわち,その≪型付けされた参照≫を構築した

mkrefany命令に与えられた≪クラス≫。)と同一でない場合,System.InvalidCastExceptionを送出

する。 

≪型≫が見つからない場合,System.TypeLoadExceptionを送出する。 

適正性 

適正なCILは,≪型付けされた参照≫が妥当な(以前に呼び出したmkrefanyによって生成された。)

型付けされた参照であることを保証する。 

正当性検証可能性 

refanyval命令は常に正当性検証可能とする。 

4.24 rethrow − 現在の例外を再送出する 

形式 

アセンブリ形式 

定義 

FE 1A 

rethrow 

現在の例外を再送出する。 

background image

372 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

スタック推移: 

…, ◊ …, 

定義 

rethrow命令は,catchハンドラ(第1章参照)の本体内でだけ使用できる。この命令は,このcatch

ハンドラが捕そくしたのと同じ例外を送出する。rethrowはオブジェクト内のスタックトレースを変更し

ない。 

例外 

元の例外を送出する。 

適正性 

適正なCILは,catchハンドラの本体内(そのcatchハンドラ内に埋め込まれた任意の例外ハンドラ

の内部という意味ではなくcatchハンドラそのものの内部。)でだけ,この命令を使用する。それ以外の

箇所でrethrowが実行されると,何らかの例外が送出される。しかし,その場合に送出される具体的な

例外は未定義とする。 

正当性検証可能性 

追加の正当性検証要件はない。 

4.25 sizeof ‒ 値型の大きさをバイト単位でスタックに入れる 

形式 

アセンブリ形式 

定義 

FE 1C<T> 

sizeof ≪型トークン≫ 値型の大きさを,バイトを単位としてunsigned int32型でスタック

に登録する。 

スタック推移 

…, ◊ …, ≪大きさ≫ (4バイト,符号なし) 

定義 

バイトを単位として型の大きさを返す。≪型トークン≫は,総称仮引数,参照型又は値型でなければな

らない。 

参照型については,返却されるサイズは,オブジェクト中に格納されている参照値によって参照されて

いるデータのサイズではなく,対応する型の参照値のサイズとする。 

注記 (根拠)値型の定義はCILが生成されてから,そのCILが実行のためにロードされるまでの間

に変更することができる。したがって,CILが生成される時点では,型の大きさは必ずしも特

定できるとは限らない。sizeof命令によって,フレームワークのクラスライブラリを呼び出

すことなく,実行時にCILコードが大きさを決定できるようになる。大きさの計算は実行時に

行ってもよく,CILをプラットフォーム固有のコードへコンパイル時に行ってもよい。sizeof

は,実装が追加することを決めたあらゆる詰物を含んで,この値型の配列の各要素によって占

有される大きさの合計を返す。特に,要素の合計の大きさと,sizeofのバイト数とは別のも

のである。 

例外 

なし。 

適正性 

≪型トークン≫は,typedef,typeref又はtypespecメタデータトークンでなければならない。 

正当性検証可能性 

この命令は常に正当性検証可能とする。 

background image

373 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

4.26 stelem ‒ 配列の要素を格納する 

形式 

アセンブリ形式 

定義 

A4 <T> 

stelem ≪型トークン≫ ≪添字≫の位置にある配列要素をスタック上の≪値≫で置き換え

る。 

スタック推移 

…, ≪配列≫, ≪添字≫, ≪値≫ ◊ … 

定義 

stelem命令は,1次元配列≪配列≫中の,native int型又はint32型の0から始まる添字≪添字≫

の要素の値を≪値≫で置き換える。配列はオブジェクトであるため,O型の値によって表現される。値は

命令中の≪型トークン≫が指定する型とする。 

例外 

≪配列≫がnullである場合,System.NullReferenceExceptionを送出する。 

≪添字≫が≪配列≫の範囲より大きい場合,System.IndexOutOfRangeExceptionを送出する。 

≪配列≫が要求された型をもっていない場合,System.ArrayTypeMismatchExceptionを送出する。 

適正性 

≪型トークン≫は,妥当なtypedef,typeref又はtypespecメタデータトークンでなければならな

い。 

≪配列≫はnull又は1次元配列でなければならない。 

正当性検証可能性 

配列の静的な型は特殊な参照型Null又は0で始まる1次元配列型の適切な型elem[]のいずれかでな

ければならない。ここで,elemは何らかの型とする。配列型がnullである場合,elemは演算対象≪型

トークン≫によって表される型とみなす。値≪添字≫は≪型トークン≫と代入互換性をもっていなければ

ならない。 

4.27 stelem.<type> − 配列の要素に値を格納する 

形式 

アセンブリ形式 

定義 

9C 

stelem.i1 

≪添字≫で指定された配列の要素を,スタック上のint8型の≪値≫
で置換する。 

9D 

stelem.i2 

≪添字≫で指定された配列の要素を,スタック上のint16型の≪値
≫で置換する。 

9E 

stelem.i4 

≪添字≫で指定された配列の要素を,スタック上のint32型の≪値
≫で置換する。 

9F 

stelem.i8 

≪添字≫で指定された配列の要素を,スタック上のint64型の≪値
≫で置換する。 

A0 

stelem.r4 

≪添字≫で指定された配列の要素を,スタック上のfloat32型の≪
値≫で置換する。 

A1 

stelem.r8 

≪添字≫で指定された配列の要素を,スタック上のfloat64型の≪
値≫で置換する。 

9B 

stelem.i 

≪添字≫で指定された配列の要素を,スタック上のi型の≪値≫で
置換する。 

A2 

stelem.ref 

≪添字≫で指定された配列の要素を,スタック上のref型の≪値≫
で置換する。 

スタック推移 

…, ≪配列≫, ≪添字≫, ≪値≫ ◊ …, 

定義 

background image

374 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

stelem命令は,1次元配列≪配列≫中の0を基点とする(int32型又はnative int型の)添字≪添

字≫の要素の値を≪値≫に置換する。配列はオブジェクトであり,よってO型の値として表現される。 

stelem.ref命令では,≪配列≫の要素に値を割り当てる前に,≪値≫を≪配列≫の要素型に暗黙的に

キャストする。正当性検証されたコードでも,このキャストは失敗することがある。したがって,

stelem.ref命令はArrayTypeMismatchExceptionを送出することがある。 

添字が0から始まらない1次元配列及び多次元配列に対しては,配列クラスはStoreElementメソッ

ドを提供する。 

例外 

≪配列≫がnullである場合,System.NullReferenceExceptionを送出する。 

≪添字≫が負又は配列の境界より大きい場合,System.IndexOutOfRangeExceptionを送出する。 

≪配列≫が要求された型の要素を保持していない場合,System.ArrayTypeMismatchExceptionを

送出する。 

適正性 

適正なCILでは,配列の添字が0から始まる1次元配列でなければならず,その宣言された要素型がこ

の命令の接尾辞の型に厳密に一致しなければならない(例えば,stelem.r4は添字が0から始まる

float32型の1次元配列にだけ適用できる。)。 

正当性検証可能性 

配列の静的な型は特殊な参照型Null又は0で始まる1次元配列型の適切な型elem[]のいずれかでな

ければならない。ここで,elemは何らかの型とする。≪配列≫の型と≪値≫の型の両方が,命令の接尾

辞と一致していなければならない。stelem.ref命令については,値と配列要素型の両方が参照型である

ことだけを要求する。 

4.28 stfld − オブジェクトのフィールドへ格納する 

形式 

アセンブリ形式 

定義 

7D<T> 

stfld ≪フィールド≫ 

オブジェクト≪オブジェクト≫の≪フィールド≫の値を≪値≫で
置換する。 

スタック推移 

…, ≪オブジェクト≫, ≪値≫ ◊ …, 

定義 

stfld命令は,≪オブジェクト≫(O型)のフィールドの値又はポインタ(native int型又は&型)

によって示されるフィールドの値を≪値≫に置き換える。≪フィールド≫は,フィールドメンバを参照す

るメタデータトークン(fieldref又はfielddef,第2章参照)とする。stfldは,スタックから,値

及びオブジェクト参照を取り出し,オブジェクトの値を更新する。 

stfld命令は,unaligned.若しくはvolatile.のいずれか又は両方の接頭辞を付けてもよい。 

例外 

≪フィールド≫がアクセス可能でない場合,System.FieldAccessExceptionを送出する。 

≪オブジェクト≫がnullであり,かつ,フィールドが静的でない場合, 

System.NullReferenceExceptionを送出する。 

メタデータの中に≪フィールド≫が見つからない場合,System.MissingFieldExceptionを送出す

る。この例外は典型的には実行時ではなく,CILをプラットフォーム固有のコードに変換する時に,検出

される。 

background image

375 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

適正性 

適正なCILは,≪フィールド≫がフィールドを参照する妥当なトークンであり,かつ,1.6で規定した

暗黙の変換を前提として,常に≪オブジェクト≫及び≪値≫が実行しようとしている代入操作に対して適

切な型になっている保証する。 

正当性検証可能性 

正当性検証可能なコードでは,≪オブジェクト≫は管理外ポインタであってはならない。 

注記 クラス初期化子の本体の外側にある静的な初期化専用フィールドの値を変更するために

stfldを使用すると,予測不能な動作になるかもしれない。しかし,それはメモリの整合性又

は型の安全性を損なうことはないため,正当性検証はそれを検査しない。 

重なりのあるオブジェクト参照フィールドにアクセスすることは,正当性検証可能ではない。 

重なり合うすべてのフィールドがアクセス可能な場合に限り,そのフィールドはアクセス可能とする。 

4.29 stobj − スタックからメモリへ値型を格納する 

形式 

アセンブリ形式 

定義 

81 <T> 

stobj ≪型トークン≫ 

あるアドレスが指す位置にある≪型トークン≫型の値をメモリへ
格納する。 

スタック推移 

…, ≪格納先≫, ≪格納元≫ ◊ …, 

定義 

≪型トークン≫が値型である場合,stobj命令は,≪格納先≫で指定されたアドレスに≪格納元≫の値

をコピーする。≪型トークン≫が参照型である場合,stobj命令は,stind.refと同じ効果をもつ。 

直前にvolatile.又はunaligned.をつけることによって,stobj命令の動作を変更することができ

る。 

例外 

不当なアドレスを検出した場合,System.NullReferenceExceptionを送出する可能性がある。 

≪型トークン≫が見つからない場合,System.TypeLoadExceptionを送出する。この例外は典型的

には,実行時ではなく,CILがプラットフォーム固有のコードに変換される時に検出される。 

適正性 

≪型トークン≫は,妥当なtypedef,typeref又はtypespecメタデータトークンでなければならな

い。 

正当性検証可能性 

スタックの最上部の値の静的な型を,何らかの型≪格納元≫とする。≪格納元≫が参照型である場合,

値は初期化されていなければならない。先行するスタックスロット上の格納先アドレス≪格納先≫の静的

な型は,≪格納先≫の型への管理下ポインタ(≪格納先の型≫&)でなければならない。最終的に,≪格

納元≫は≪型トークン≫と代入互換性をもっていなければならず,≪型トークン≫は≪格納先の型≫の部

分型になっていなければならない。≪格納先の型≫が参照型でない場合,部分型についてのこの規定は,

≪格納元の型≫が≪格納先の型≫(これは≪型トークン≫と同じものである)と代入互換性をもっていな

ければならないことを意味する。 

4.30 stsfld − クラスの静的フィールドに格納する 

形式 

アセンブリ形式 

定義 

80 <T> 

stsfld ≪フィールド≫ ≪フィールド≫の値を≪値≫で置き換える。 

background image

376 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

スタック推移 

…, ≪値≫ ◊ …, 

定義 

stsfld命令は,静的フィールドの値をスタックから取り出した値で置き換える。≪フィールド≫は,

メタデータトークン(fieldref又はfielddef,第2章参照)であり,静的フィールドメンバを参照し

なければならない。stsfldは,スタックから値を取り出し,静的フィールドをその値で更新する。 

stsfld命令には,volatile. 接頭辞を付けることができる。 

例外 

≪フィールド≫がアクセス可能でない場合,System.FieldAccessExceptionを送出する。 

メタデータの中に≪フィールド≫が見つからない場合,System.MissingFieldExceptionを送出す

る。一般に,実行時ではなく,CILがプラットフォーム固有のコードに変換される時に,この例外が検出

される。 

適正性 

適正なCILは,≪フィールド≫が静的フィールドを参照する正当なトークンであり,かつ,1.6で規定

した暗黙の変換を前提として,≪値≫が実行される代入にとって適切な型をもつことを保証する。 

正当性検証可能性 

注記 クラス初期化子の本体の外側にある静的な初期化専用フィールドの値を変更するために

stsfldを使用することは,予測不能な振る舞いにつながるかもしれない。しかし,それはメ

モリの整合性又は型の安全性を損なうはずはなく,したがって,それは正当性検証によって試

験されない。 

4.31 throw -例外を送出する 

形式 

アセンブリ形式 

定義 

7A 

throw 

例外を送出する。 

スタック推移 

…, ≪オブジェクト≫ ◊ …, 

定義 

throw命令はスタック上に例外オブジェクト(O型)を送出し,スタックを空にする。例外機構の詳細

については,第1章を参照する。 

注記 CLIではどんなオブジェクトも送出することが可能だが,言語相互運用性を確保するために使

用する必要のある特定の例外クラスについて,CLSで定義している。 

例外 

≪オブジェクト≫がnullである場合,System.NullReferenceExceptionを送出する。 

適正性 

適正なCILは,≪オブジェクト≫が常にnull又はオブジェクト参照,すなわち,O型であることを保証

する。 

正当性検証可能性 

追加の正当性検証要件はない。 

4.32 unbox -ボックス化された値型を,その生の形式へ変換する 

形式 

アセンブリ形式 

定義 

background image

377 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

79 <T> 

unbox ≪値型≫ 

そのボックス化された表現≪オブジェクト≫から,値型データを抽出
する。 

スタック推移 

…, ≪オブジェクト≫ ◊ …, ≪値型のポインタ≫ 

定義 

値型はCLIにおいて,二つの異なる表現(第1章参照)をもつ。 

− 値型が別のオブジェクト内に埋め込まれている場合に使用される“生の”形式。 

− 独立した実体として存在することを可能にするため,値型の中のデータがオブジェクトの中に包まれ

た(箱に入れられた。)状態の“ボックス化された”形式。 

unbox命令は,値型のボックス化された表現である≪オブジェクト≫(O型)を≪値型のポインタ≫(制

御された変更可能な管理下ポインタ,1.8.1.2.2参照,&型)すなわち,ボックス化解除された形式に変換す

る。≪値型≫は,≪オブジェクト≫内に含まれた値型の型を示すメタデータトークン(typeref,typedef

又はtypespec)とする。≪オブジェクト≫内に含まれている値の型は≪値型≫代入互換でなければなら

ない。 

注記 これはenum型に対して効果をもつ。第2章の14.3を参照する。 

オブジェクト内で使用するために値型のコピーを必要とするボックス化と異なり,ボックス化解除では

オブジェクトから値型をコピーする必要はない。一般に,それは単にボックス化されたオブジェクトの内

部で既に存在する値型のアドレスを算出するだけとする。 

注記 典型的には,unboxは単にボックス化された型の中に既に存在している値型のアドレスを計算

する。この方法は,null許容の値型のボックス化解除である場合には適用できない。

Nullable<T>の値が,ボックス化操作を行っている期間に,ボックス化された型Tに変換さ

れている場合,処理系はヒープ上の新しいNullable<T>を操作し,新たに割り付けられたオ

ブジェクトへのアドレスを算出するに違いない。 

例外 

≪オブジェクト≫がボックス化された値型ではなく,≪値型≫がNullable<T>であり,≪オブジェク

ト≫がボックス化されたTでない場合,又は,≪オブジェクト≫の中に含まれた値の型が≪値型≫と代入

互換でない場合,System.InvalidCastExceptionを送出する。 

≪オブジェクト≫がnullで≪値型≫がnull許容でない値型(第1章の8.2.4参照)である場合,

System.NullReferenceExceptionを送出する。 

該当する型を見つけることができない場合,System.TypeLoadExceptionを送出する。この例外は,

典型的には実行時ではなく,CILをプラットフォーム固有のコードに変換する時に発生する。 

適正性 

適正なCILは,≪値型≫が何らかの値型のためのtyperef,typedef又はtypespecのメタデータト

ークンであり,≪オブジェクト≫が常にオブジェクト参照(すなわちO型)であることを保証する。≪値

型≫がNullable<T>型である場合,ボックス化されたインスタンスはT型でなければならない。 

正当性検証可能性 

追加の正当性検証要件はない 

4.33 unbox.any -ボックス化された型を値に変換する 

形式 

アセンブリ形式 

定義 

background image

378 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

79 <T> 

unbox.any ≪型トー
クン≫ 

ボックス化された表現である≪オブジェクト≫から,値型を抽出す
る。 

スタック推移 

…, ≪オブジェクト≫ ◊ …, ≪値又はオブジェクト≫ 

定義 

値型をボックス化した形式に適用した場合,unbox.any命令は≪オブジェクト≫(O型)内に含まれ

ている値を抽出する。(これは直後にldobjが続くunboxと等価とする。)参照型に適用した場合,

unbox.any命令は,castclass ≪型トークン≫と同じ効果をもつ。 

≪型トークン≫が型仮引数である場合,実行時の動作はその型仮引数を現実にインスタンス化したもの

によって決まる。 

例外 

≪オブジェクト≫がボックス化された値型ではなく,≪型トークン≫がNullable<T>であり,≪オブ

ジェクト≫がボックス化されたTでない場合,又は,≪オブジェクト≫の中に含まれた値の型が≪型トー

クン≫と代入互換でない場合,System.InvalidCastExceptionを送出する。 

≪オブジェクト≫がnullで≪型トークン≫がnull許容でない値型(第1章の8.2.4参照)である場合,

System.NullReferenceExceptionを送出する。 

適正性 

≪オブジェクト≫は参照型でなければならない。 

正当性検証可能性 

オブジェクト参照≪オブジェクト≫は初期化されていなければならない。型オペランド≪型トークン≫

は,byref,byref-like又はvoid型であってはならない。スタックの左側の値の型は≪型トークン≫とする。 

注記(根拠) unbox.any命令とunbox命令の両方をもっている理由は二つある。 

1) 

unbox命令とちがい,値型に対して,unbox.anyは値のアドレスではなく値そのものをス

タック上に残していく。 

2) 

unboxに対する型オペランドは,表現できるのは値型及び総称の値型をインスタンス化した

ものだけであるという制限をもつ。 

第4章 プロファイル及びライブラリ 

概要 

注記 コンパイラの作成者はファイル形式,命令集合の設計,及び共通型システムに関する問題を最

も重視するが,アプリケーションプログラマの関心は,使用する言語に用意されているプログ

ラムライブラリの多さにある。共通言語基盤(CLI)は共通言語仕様(CLS,第1章参照)を規

定し,共通言語仕様は,複数のプログラム言語で幅広く使用されることを目的とした場合に,

言語の外的側面(メソッド識別情報など)を規定するために使用すべきものである。可能な限

り多くのプログラム言語から使用できるものとすることがCLIライブラリの目的のため,ライ

ブラリの全機能はCLS合致の型及び型メンバを通して利用可能である。 

このCLIライブラリは,次の要件を満たすことを目指して設計されている。 

− プログラム言語全般を対象とする。 

− 全体を通して設計に一貫性がある。 

379 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

− JIS X 3010プログラム言語Cの機能と同等である。 

− より新しいプログラムの枠組み,とりわけ,ネットワーキング,XML,実行時の型検査,イ

ンスタンスの作成,及び動的なメソッドディスパッチの機能を提供する。 

− 個々のライブラリを相互依存を最小限とした自己矛盾のないライブラリとする。 

この章は,CLIライブラリの概要及びこれらをプロファイル及びライブラリへと分割する仕様を規定す

る。この章の一部とみなされるXML形式ファイルに,CLIライブラリの各型に関する詳細を示す。CLI

ライブラリの標準仕様はXML形式で提供されるが,XSL変換を行うことで,クラスライブラリに関する

情報を簡単に表示可能な形式にすることができる。 

注記 仮CLIライブラリの標準仕様を記述するXML形式ファイルは,日本工業規格では提供されて

いない。ECMA 335,ISO/IEC 23271の一部として入手できる。 

注記 第6章には,CLIライブラリの定義に使用されるプログラミング規約を示した附属書(参考)

が含まれる。その規約は,ライブラリを使用する上で大いに役立つ。ライブラリを追加すると

き,すなわち,標準として提供される以外のライブラリを作成するときは,この規約に従うこ

とが推奨される。 

ライブラリ及びプロファイル 

ライブラリ及びプロファイルは次のとおり定義され,標準規格に適合すべく作成される。これらは,CLI

の実装に含まれることになる一連の機能を規定するものとし,そのCLIによって実行されるプログラムか

ら使用可能な型の集合とする。 

注記 仮想実行システム(VES)におけるライブラリ及びプロファイルの直接的な対応は何ら必要と

されるものではない。これらはメタデータに表されるものではなく,また,CLIの実装の構造

又は性能に影響を与えるものではない。ライブラリ及びプロファイルはアセンブリ(配備単位)

もその範囲とでき,個々のライブラリ又はプロファイルに含まれる型名に共通接頭辞("名前空

間")を含めなくてよい。 

概して,実行時に特定の機能が使用可能であることを確認する手段はなく,また,特定のプロファイル

又はライブラリが使用可能であることを調べる手段もない。ただし,自己反映ライブラリがあることによ

って実行時に特定の型及びメンバがあるかどうかを調べることが可能である。 

2.1 

ライブラリ 

一つのライブラリは次の3点を規定するものである。 

1) 用意されるべき型の集合。アセンブリへの区分けを含む。(標準ライブラリの型は,mscorlib,

System,及びSystem.Xmlの三つのアセンブリに含まれる。各型の規定に,その型が含まれるア

センブリを示す。 

2) 使用可能なCLIの機能の集合。 

注記 任意の特定のライブラリに必要とされる一連の機能は,CLI機能の集合全体の部分集合と

なる。箇条5に記述された各ライブラリには,そのライブラリを提供する実装のために必

要なCLI機能を規定した文章を含む。 

3) 他のライブラリにおいて規定された型に対する変更点。通常,これらの変更点は,他のライブラリ

に属するメソッド及びインタフェースの型への追加及びこれらのライブラリの型のメソッドによっ

て投げられる可能性がある追加の例外型とする。これらの変更点は,機能追加又は特定の動作があ

らかじめ規定されていない場合にだけ提供されるべきものであり,あらかじめ規定された動作を変

380 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

更するために提供してはいけない。 

例 拡張数値ライブラリの場合を想定する。これが基本データ型であるDoubleを提供するため,こ

のライブラリは,基底クラスライブラリの一部であるSystem.Convertクラスにメソッド

ToDoubleが追加されることも規定する。また,例外型として 

System.NotFiniteNumberExceptionも追加定義し,他のライブラリに含まれる既存のメソ

ッドでこの例外を返すもの(これらのメソッドがなかった場合に発生する。)を規定する。 

ライブラリのXML仕様には,各型が属するライブラリを型ごとに規定する。拡張数値(5.7参照)など

のある一つのライブラリの一部であるが,型がBase Class Library(5.3参照)などの他のライブラリ(BCL)

に属するメンバ[Console.WriteLine(float)など]については,そのメソッドを定義するライブラ

リがXMLに明示される(箇条7参照)。 

2.2 

プロファイル 

プロファイルとはライブラリの集合であり,特定のレベルの機能を一貫性をもったまとまりとして形式

化するために区分けされたものである。CLI規格適合処理系は実装するプロファイル及び追加分として提

供するすべてのライブラリを規定しなくてはならない。カーネルプロファイル(3.1参照)はすべてのCLI

の規格適合処理系に含まれなくてはならない。したがって,カーネルプロファイルの一部である全ライブ

ラリ及びCLI機能は,すべての規格適合処理系で使用可能となる。この最小限の機能集合は,箇条4に規

定する。 

注記 ここにその根拠を示す。ライブラリを統合するための規則は複雑なものとなる。その理由は,

各ライブラリは他のライブラリに定義された型にメンバを追加することができることによる。

少数のプロファイルを規格化することによって,各プロファイルの一部にあるライブラリの全

相互関係を規定する。個々のプロファイルは,デバイス,コンパイラ,ツール,及びアプリケ

ーションの製造業者に対して一貫した対象を示す。各プロファイルは,CLI機能,資源制約及

び実装の複雑さとの間のトレードオフを規定する。極少数のプロファイルを定義することによ

って,各プロファイルの需要を拡大し,この方法で,広範囲な実装及びツールセットにわたる

アプリケーションのクラスに対し,各プロファイルが望ましい対象となることを意図する。 

2.3 

ライブラリとプロファイルとの関係 

この規格は,2種の標準プロファイル(箇条3参照)及び7種の標準ライブラリ(箇条5参照)を規定

する。次の図にライブラリとプロファイルとの関係を示す。 

background image

381 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

拡張配列ライブラリ及び拡張数値ライブラリはいずれのプロファイルにも含まれないが,いずれのプロ

ファイルとも組み合わせることが可能である。組み合わせることで,特定のメソッド,例外,及びインタ

フェースをそのプロファイルで規定された型に追加する。 

標準プロファイル 

標準プロファイルには次の2種がある。CLI規格適合処理系の最小のものは,カーネルプロファイルと

する。一方,小型プロファイルは,より資源の豊富なデバイス集合を対象とするアプリケーションにとっ

て有益な追加機能を含む。 

CLI規格適合処理系は,この規格に規定され,かつ特定のプロファイル(第3章)が提供しない機能に

遭遇した時に,しかるべき例外(例えば,System.Not-ImplementedException, 

System.MissingMethodException,又はSystem.ExecutionEngineException)を送出しなくて

はならない。 

注記1 実装者は,提供しない機能を静的に検知するツールを提供することを考慮することが望まし

い。それがあれば,実行前にこうした機能があるかどうかを検査するプログラムを使用者は

使用できる。 

注記2 CLI規格適合処理系の製造者は,提供する標準ライブラリ及び標準プロファイルの構成がど

れであるかを厳密に指定することが望ましい。 

注記3 ここでの“機能”とは,拡張数値ライブラリを提供しないCLI上で,メソッドの実装上の浮

動小数点CIL命令の使用などになり得る。また,この“機能”は,特定のライブラリが実装

されている場合にだけ存在するこの規格で規定されているメソッドに対する,そのライブラ

リが提供されていないCLIの実装上で実行されているコードからの呼出しになるかもしれな

い。 

382 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

3.1 

カーネルプロファイル 

このプロファイルは,CLI規格適合処理系の最小のものである。これには,近年のプログラム言語のク

ラスライブラリ,及びこのCLIを対象とするコンパイラに必要とされる型において,一般的な型が含まれ

る。 

内容 基底クラスライブラリ,実行時基盤ライブラリ 

3.2 

小型プロファイル 

このプロファイルは,適量の物理メモリだけでデバイス上の実装を可能だが,カーネルプロファイルだ

けである場合よりも多くの機能を提供することを目的として設計されたものである。また,これには提案

されたECMAScript小型プロファイルの実装に必要なものすべてが含まれる。 

内容 カーネルプロファイル,XMLライブラリ,ネットワークライブラリ,自己反映ライブラリ。 

カーネルプロファイル機能要件 

すべてのCLI規格適合処理系は,少なくともカーネルプロファイルを提供するものとする。結果として,

そのカーネルプロファイルに必要な全CLI機能はすべての規格適合処理系に実装されなければならない。

この箇条では,必ずしも必要でない機能集合を列挙することによって,最小限の機能集合を定義する。す

なわち,最小限の規格適合処理系は,この箇条で示された機能以外のすべてのCLI機能を実装しなければ

ならない。箇条5に規定されるように,各ライブラリの機能要件は,この節に記載した制限項目への参照

によって定義される。参照しやすくするため,各機能には箇条又は細分箇条の見出しとなる名前を付加す

る。ライブラリに規定された機能要件の追加条項がない場合,この箇条に記述されたカーネルプロファイ

ルの機能だけが必す(須)とみなされなくてはならない。 

4.1 

カーネルプロファイルから除外される機能 

この規格で規定される,次の内部データ型及び構築要素は,カーネルプロファイルだけに適合するCLI

実装の必す(須)要件ではない。それ以外の全CLI機能は必す(須)要件とする。 

4.1.1 

浮動小数点 

浮動小数点の機能集合は,使用者可視の浮動小数点データ型であるfloat32及びfloat64,並びに,

浮動小数点数の内部表現に対する対応から構成される。 

省略時 これらのデータ型を明確に扱うCIL命令は,System.NotImplementedException例外を送

出する。これらの命令は,次のとおりとする。ckfinite,conv.r.un,conv.r4,conv.r8,ldc.r4,ldc.r8,ldelem.r4,

ldelem.r8,ldind.r4,ldind.r8,stelem.r4,stelem.r8,stind.r4,stind.r8。浮動小数点データ型を含む識別情報

を参照するすべての試みに対し,System.NotImplementedException例外を送出する。例外が発生す

る明確な時期は規定されない。 

注記 これらの制限によって,VESは浮動小数点データに遭遇しないことが保証される。したがって,

演算命令(add命令など)の実装は,これらの型を処理する必要はない。 

ライブラリ部分: 拡張数値(5.7参照) 

4.1.2 

非ベクトル配列 

非ベクトル配列機能集合は,2次元以上,又は0以外の下限の配列への対応を含む。これには,これら

の配列の識別情報の参照,これらの配列の実行時表現,及びこれらの配列とプラットフォーム固有なデー

タ型との間で双方向に行われる組み換えに対する対応が含まれる。 

省略時: 非ベクトル配列を含む識別情報を参照するすべての試みに対し 

System.NotImplementedException例外を送出する。例外が発生する明確な時期は規定されない。 

383 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

注記 一般型System.Arrayはカーネルプロファイルの一部であり,すべてのCLI規格適合処理系

で使用可能である。非ベクトル配列機能集合を提供しない実装は,このクラスのすべてのイン

スタンスは正しくベクトル配列であるとみなすことができる。 

ライブラリ部分: 拡張配列(5.8参照) 

4.1.3 

自己反映 

自己反映機能集合はデータ型の完全な自己反映を提供する。このすべての機能は自己反映ライブラリの

メソッドを介して開示される。 

省略時 カーネルプロファイルは,あいまいな型であるSystem.Typeを指定する。これのインスタン

スは,システム内の全型を独自に表現し,型の名前へのアクセスを提供する。 

注記 カーネルプロファイルだけである場合に必す(須)要件はない。例えば,型のメンバを決定す

るためには,動的に型のインスタンスを作成するか,又はSystem.Typeのインスタンスを与

えられた型のメソッドを呼び出す。これによって,自己反映ライブラリが使用できる時に必す

(須)要件があることに比べ,CLIの実装を簡略化できる。 

ライブラリ部分: 自己反映(5.5参照) 

4.1.4 

アプリケーション領域 

アプリケーション領域機能集合は,複数のアプリケーション領域に対応する。カーネルプロファイルで

は,単一のアプリケーション領域が存在することが必要とする。 

省略時 アプリケーション領域を作成するためのメソッド(基底クラスライブラリの部,5.3参照)は,

System.NotImplementedException例外を送出する。 

ライブラリ部分: (なし) 

4.1.5 

リモーティング 

リモーティング機能集合は,リモートメソッド呼出しを提供する。これは,第1章に示すように,主に

System.MarshalByRefObjectクラス専用の意味規則を介して提供される。 

省略時 System.MarshalByRefObjectクラスは特別な意味のない単純なクラスとして扱われる。 

ライブラリ部分: (なし) 

4.1.6 

可変引数 

可変引数機能集合は,可変長の引数並び及び実行時に型付けされるポインタを提供する。 

省略時 vararg呼出し規則,又は可変引数メソッド(第2章参照)と関連付けられた識別情報の符号化

を参照するすべての試みは,System.NotImplementedException例外を送出する。CILのarglist,

refanytype,mkrefany,及びrefanyval命令を使用したメソッドは,System.NotImplementedException

例外を送出する。例外が発生する明確な時期は規定されない。System.TypedReference型を定義する

必要はない。 

ライブラリ部分: Vararg(5.9参照) 

4.1.7 

フレーム拡張 

フレーム拡張機能集合は,スタックフレームの動的な拡張を提供する。 

省略時 CILのlocalloc命令を使用したメソッドは,System.NotImplementedException例外を送

出する。例外が発生する明確な時期は規定されない。 

ライブラリ部分: (なし) 

4.1.8 

フィルタ適用例外 

フィルタ適用例外機能集合は,例外に対する使用者供給フィルタを提供する。 

384 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

省略時 CILのendfilter命令を使用するメソッド,又は非nullなfilterstart(第1章参照)を含む

exceptionentryが使用されたメソッドは,System.NotImplementedException例外を送出する。

例外が発生する明確な時期は規定されない。 

ライブラリ部分: (なし) 

標準ライブラリ 

各ライブラリの詳細な内容,すなわち,ライブラリが提供する型及び他のライブラリの型に対する変更

点については,XML形式で提供される。この節では,各ライブラリの目的についての概略を述べるととも

に,各ライブラリ,ひいてはカーネルプロファイルに必要なCLI機能を規定する。 

5.1 

一般的なコメント 

メソッドの文書において,特に記述されていない場合は,コピー命令はdeep copyではなく,shallow copy

を意味するものとする。 

メソッドには省略時の値をもつものがある。参照型のでは,省略時の値はnullとする。null許容値型で

は,省略時の値は,HasValueがfalseを返す。null許容でない値型では,省略時の値はすべてのビットが

ゼロ(Booleanではfalseを表し,すべての算術型ではゼロを表す。)。 

5.2 

実行時基盤ライブラリ 

実行時基盤ライブラリは,カーネルプロファイルの一部とする。このライブラリは,CLIを対象とする

コンパイラ及び第2章に規定されるファイル形式にあるストリームから動的に型をロードするために必要

となる機能に必要なサービスを提供する。例えば,このライブラリは正しい形式でないストリームがロー

ドされたときに送出されるSystem.BadImageFormatExceptionを提供する。 

XMLで使用される名称 RuntimeInfrastructure 

CLI機能要件 なし 

5.3 

基底クラスライブラリ(BCL) 

基底クラスライブラリは,カーネルプロファイルの一部とする。これは,近年のプログラム言語を対象

とした簡潔な実行時ライブラリである。C#言語の実行時ライブラリの標準であり,CLIの標準ライブラリ

の一つでもある。このライブラリは,CLIの組込みのデータ型を表現するための型,ファイルへの単純な

アクセス,カスタム属性,セキュリティ属性,文字列操作,書式設定,ストリーム,コレクションなどを

提供する。 

XMLで使用される名称 BCL 

CLI機能要件 なし 

5.4 

ネットワークライブラリ 

ネットワークライブラリは,小型プロファイルの一部とする。このライブラリは,ネットワークポート

への直接アクセスを含む単純なネットワークサービス,及びHTTPに対応する。 

XMLで使用される名称 Networking 

CLI機能要件 なし 

5.5 

自己反映ライブラリ 

自己反映ライブラリは小型プロファイルの一部とする。このライブラリは,すべて型の記述に基づく,

型の構造の検査,型のインスタンス生成,及び型のメソッドの呼出し機能を提供する。 

XMLで使用される名称 Reflection 

CLI機能要件 自己反映を提供しなければならない(5.1参照)。 

385 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

5.6 

XMLライブラリ 

XMLライブラリは,小型プロファイルの一部とする。このライブラリは,XMLを対象とした単純な“引

出し型”のパーサを提供する。資源制約のあるデバイス向けに設計されており,また,単純な使用者モデ

ルを提供する。CLI規格適合処理系でこのXMLライブラリを含むものは,ネットワークライブラリ(5.4

参照)も実装しなければならない。 

XMLで使用される名称 XML 

CLI機能要件 なし 

5.7 

拡張数値ライブラリ 

拡張数値ライブラリは,いずれのプロファイルの一部でもないが,任意のCLI実装の一部として供給し

てよい。このライブラリは,浮動小数点(System.Single,System.Double)及び拡張精度

(System.Decimal)データ型に対応する。基底クラスライブラリ同様,このライブラリはC#規格から

直接参照される。 

注記1 このライブラリを使用するプログラマには,これらのデータ型のどの算術演算が主にハード

ウェア対応を介して実装されているかを実装に指定することが有益である。 

注記2 その根拠を述べると,一般的に使用される処理系の一部がこのデータ型に直接対応していな

いため,この拡張数値ライブラリは実装から分離されている。ソフトウェアエミュレーショ

ンを提供することは可能だが,通例,性能の差が非常に大きいため(1 000倍以上),基盤と

なる実装がハードウェアベースであるかどうかが明確でない状態で浮動小数点演算を使用す

るソフトウェアを構築することは合理的でない。 

XMLで使用される名称 ExetendedNumerics 

CLI機能要件 浮動小数点については,4.1.1を参照する。 

5.8 

拡張配列ライブラリ 

このライブラリは,いずれのプロファイルの一部でもないが,任意のCLI実装の一部として供給してよ

い。このライブラリは,非ベクトル配列に対応する。すなわち,2次元以上の次元をもつ配列,又は0以

外の下限をもつ配列である。 

CLI機能要件 非ベクトル配列については,4.1.2を参照する。 

5.9 

Varargライブラリ 

Varargライブラリは,いずれのプロファイルの一部でもない。可変長実引数並びを扱うための機能を提

供する。任意のCLI実装の一部として供給してよい。このライブラリは,非ベクトル配列に対応する。す

なわち,2次元以上の次元をもつ配列,又は0以外の下限をもつ配列である。 

XMLで使用される名称 Vararg 

CLI機能要件 なし 

5.10 並列ライブラリ 

このライブラリは,いずれのプロファイルの一部でもないが,任意のCLI実装の一部として供給するこ

とができる。拡張されたスレッド処理ライブラリには,次の二つの目的がある。 

1) 並列処理を容易にし,熟練のプログラマでなくとも,マルチスレッド化されたCPUを有効活用でき

るようにする。プロファイルでは,規模適応性よりも手軽さが重視されている。 

2) 仮想マシン又はソース言語の変更を要求しない。プロファイルのすべての機能は,既存のCLI上の

ライブラリとして実装できる。プロファイルは,委譲の機能を提供する任意のCLI言語と組み合わ

せて使用できる。 

386 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

次に,ループクラスの階層構造を示す。 

ParallelLoop 

 ParallelWhile 

 ParallelForEach 

 ParallelFor 

基底クラスParallelLoopは,値の集団に対する並列ループ処理を行う場合の共通機能をまとめたも

のである。三つの派生クラスは,3種類の共通並列ループ処理に区別される。処理の過程で集団が大きく

なるような場合には,ParallelWhileを使用する。そうでなければ,集団にIEnumerableを実装し,

ParallelForEachを使用する。集団に対しint32による添字指定が可能である場合は,ParallelFor

を使用する。 

固有の状況に使用するループの種類を選択する場合は,ループを直列的に記述したらどうなるかという

観点で検討する。ループを“for (int i=0; i<n; ++i )”を使って記述できる場合,かつ,ループの

実行前にnが既知である場合は,ParallelForを使用する。集団がforeachの実行中に変更されず,かつ,

その集団に対してループをforeach文で記述できる場合は,ParallelForEachを使用する。ループを

“while (集団が空でない) {集団から項目を削除して処理する}”で記述できる場合は,ParallelWhileを

使用する。ParallelForは他と比べて極めて効率的であるため,可能であればParallelForを使用す

る。 

XMLで使用される名称 Parallel 

CLI機能要件 BCL 

システムライブラリに対する実装固有の変更 

実装者は,追加機能の提供を目的として,この規格に規定された型を拡張又は変更することが奨励され

る。ただし,実装者は,“System.”で始まり,特別な標準公開かぎ(鍵)を伴う型名は標準ライブラリ

によって使用されることを意味することに留意しなければならない。このような型名は,現在使用されて

いないものでも,この規格の将来のバージョンにおいて定義されるかもしれない。 

標準ライブラリに対してコンパイルされたプログラムが,標準ライブラリの拡張又は変更が含まれる実

装上で実行された時に動作するようにするには,こうした拡張又は変更は,次の規則に従ったものでなけ

ればならない。 

− 仮想メソッドによって規定された契約が,元のクラスを上書きする新しいクラスで保持されていなけ

ればならない。 

− 新しい例外を送出することができるが,可能であれば,それらの例外は完全に新しい例外の型ではな

く,あらかじめ規定された例外の派生クラスとしなければならない。標準ライブラリに規定された型

のメソッドによって開始される例外は,System.Exceptionから導出されなければならない。 

− インタフェース及び仮想メソッドは既存のインタフェースに追加してはならない。また,これらは,

クラスが実装を提供しない限り,抽象クラスに追加してはならない。 

注記 ここにその根拠を述べる。インタフェース及び仮想メソッドは,これが実装を伴う場合にだ

け追加できる。これによって,そのインタフェース又はメソッドがなかったときに記述され

たプログラムも動作し続けることができる。 

− インスタンスメソッドは仮想メソッドとして実装されてはならない。 

注記 この規格にインスタンスとして規定されたメソッド(非静的,非仮想)は,仮想メソッドと

background image

387 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

して実装することを許可されない。これは,コンパイル時に実装供給ライブラリを用いて可

搬性がないファイルが作成される可能性を減らすことによる。コンパイラは仮想メソッドと

インスタンスメソッドとの区分に依存する必要はないが,使用者は不注意に仮想メソッドを

上書きすることがあり得るため,その結果可搬性がないコードが作成されることがあり得る。

コンパイル時に使用するため,この規格に対応する専用ファイルを提供する方法は,使用者

エラーが発生しやすい。 

− フィールド及び非仮想メソッドのアクセス可能性は,この規格で規定したものよりも拡大することが

できる。 

注記 次の一般的な拡張は,これらの規則によって許可される。 

− 既存の型に新しいメンバを追加する。 

− 具象(非抽象)クラスは,この規格で定義されないインタフェースを実装することができる。 

− フィールド(値)を列挙に追加する。 

− 実装は,この規格に規定された型と,その基底型として定義された型との間の階層に新しい

型を追加することができる。すなわち,この規格は,型間の継承関係を規定するが,直接的

な基底型を規定するものではない。 

− 実装は,既存の仮想メソッドを上書きすることができる。その場合は,上書きするメソッド

はもとの規約を満たしていなくてはならない。 

注記 ここにその根拠を述べる。実装において,複数の型に機能を分割して非標準の拡張機構を提供

することが意図かもしれない,又は,新しい基底型を通して非標準の機能を提供することを行

いたいかもしれない。プログラムがこれらの非標準の型を参照しない限り,CLI規格適合処理

系全体にわたって,これらは可搬となる。 

XML仕様 

7.1 

意味規則 

このXML仕様は,図1 XML DTDの文書型定義(DTD)に適合する。規定されたライブラリに含まれ

る型だけがこのXMLに含まれる。 

要素及び属性には,次の3種類がある。 

− 規定:要素又は属性のうち,このXML仕様がそれらなしでは不完全となるようなもの。 

− 参考:要素又は属性のうち,このXML仕様を明確にするための助けとなる情報を規定するが,それ

らなしでもこのXML仕様が成立するもの。 

− 描出及び書式設定: 要素又は属性のうち,XML描出ツールを補助するための情報を規定するもの。 

明示的に示す場合を除き,要素又は属性に関連付けられたテキスト(#PCDATA,#CDATAなど)は,明

確に規定されない限り,関連付けられた対象である要素又は属性に従って,(図に記述されたとおり)規定

又は参考となる。 

注記 DTDの要素及び属性の多くは,描出を目的とする。 

<?xml version="1.0" encoding="UTF-8"?> 

<!ELEMENT AssemblyCulture (#PCDATA)> 

(規定)現在の型を定義するアセンブリの文化圏を指定する。現在,この値は常に“none”

に設定されている。将来使用するために予約されている。 

background image

388 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

<!ELEMENT AssemblyInfo (AssemblyName, AssemblyPublicKey, 

AssemblyVersion, AssemblyCulture, Attributes)> 

(規定)与えられた型のアセンブリに関する情報を指定する。ここの情報は,第2章に記

述されたとおり,アセンブリのメタデータの節に相当し,AssemblyName,

AssemblyPublicKey,AssemblyVersion,AssemblyCulture及びAttributes要

素の情報を含む。 

<!ELEMENT AssemblyName (#PCDATA)> 

(規定)与えられた型が属するアセンブリの名前を指定する。例えば,BCL内のすべての

型は“mscorlib”アセンブリのメンバである。 

<!ELEMENT AssemblyPublicKey (#PCDATA)> 

(規定)アセンブリの公開かぎ(鍵)を指定する。この公開かぎ(鍵)は,128ビット値

で表現される。 

<!ELEMENT AssemblyVersion (#PCDATA)> 

(規定)アセンブリのバージョンを2.0.x.yの形式で指定する。ここでは,xはビルド

番号,yは版番号とする。 

<!ELEMENT Attribute (AttributeName, Excluded, ExcludedTypeName?, 

ExcludedLibraryName?)> 

(規定)型又は型のメンバのカスタム属性用のテキストを指定する。これには,属性名,

及び属性の型自体が他のライブラリに包含されるかどうかが含まれる。 

<!ELEMENT AttributeName (#PCDATA)> 

(規定)型又は型のメンバに関連付けられたカスタム属性の名前を指定する。また,これ

には属性をインスタンス化するために必要なデータが含まれる。 

<!ELEMENT Attributes (Attribute*)> 

(規定)与えられた型又は型のメンバの属性一覧を指定する。 

<!ELEMENT Base (BaseTypeName?, ExcludedBaseTypeName?, 

ExcludedLibraryName?)> 

(規定)現在の型の基底型に関連付けられた情報を指定する。ExcludedBaseTypeName

要素及びExcludedLibraryName要素がこの要素に指定されることはまれだが,現在の

ライブラリにない型から型を継承した場合に必要となる。 

<!ELEMENT BaseTypeName (#PCDATA)> 

(規定)型の継承元のクラス(型の基底クラスなど)の完全限定名を指定する。 

<!ELEMENT Docs (summary?, altmember?, altcompliant?, param*, returns?, 

value?, exception*, threadsafe?, remarks?, example?, permission?)> 

(規定)与えられた型又は型の文字による文書を指定する。 

<!ELEMENT Excluded (#PCDATA)> 

(規定)ʻ0ʼ又はʻ1ʼによって,与えられたメンバを与えられたライブラリがない状態で

現在の型から除外できるかどうかを指定する。ʻ0ʼは除外できないことを指定する。 

<!ELEMENT ExcludedBaseTypeName (#PCDATA)> 

(規定)与えられたライブラリが実装にある場合に,現在の型が継承しなければならない

background image

389 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

型の完全限定名を指定する。ライブラリ名はExcludedLibraryName要素に指定する。

この例として,System.Objectから継承するSystem.Typeクラスがあるが,自己反映

ライブラリがある場合,System.Reflection.MemberInfoから継承しなければならな

い。 

<!ELEMENT ExcludedLibrary (#PCDATA)> 

(規定)型の与えられたメンバの実装が必す(須)となる条件として,提供される必要が

あるライブラリを指定する。例えば,System.Console.WriteLine(double)は,

ExtendedNumericsライブラリが使用可能な場合にだけ実装の必要がある。 

<!ELEMENT ExcludedLibraryName (#PCDATA)> 

(規定)この要素は,カスタム属性の記述にだけ使用される。記述された属性を定義する

ライブラリ名を指定する。例えば,System.Text.StringBuilder(C#では,これは添

字子。)に指定されたメンバ名がない場合に呼び出されるメンバを“Chars”と呼ぶ。これ

に必要とされる属性はSystem.Reflection.DefaultMemberAttributeである。これ

は,RuntimeInfrAstructureライブラリにある。この要素は,ExcludedTypeName

要素とともに使用される。 

<!ELEMENT ExcludedTypeName (#PCDATA)> 

(規定)メンバが与えられた属性を問題なく指定するために必要となる属性の完全限定名

を指定する。この要素は,ExcludedLibraryName要素と関連付けられ,属性に使用さ

れる。 

<!ELEMENT Interface (InterfaceName, Excluded)> 

(規定)型が実装するインタフェースに関する情報を指定する。この要素は,そのインタ

フェース名,及びインタフェースが現在のライブラリに必す(須)となる条件として他の

ライブラリが必要かどうかを指定するサブ要素が含まれる。 

<!ELEMENT InterfaceName (#PCDATA)> 

(規定)型が実装する完全限定インタフェース名を表現する。 

<!ELEMENT Interfaces (Interface*)> 

(規定)型が実装するインタフェースがあれば,その情報を指定する。型によって実装さ

れる各インタフェースにつき,一つのInterface要素がある。 

<!ELEMENT Libraries (Types+)> 

(規定)これは根要素である。この規格の全クラスライブラリに必要な全情報を指定する。

これには,型すべてと,それに属する子要素すべてが含まれる。 

<!ELEMENT Member (MemberSignature+, MemberType, Attributes?, 

ReturnValue, Parameters, MemberValue?, Docs, Excluded, 

ExcludedLibrary*)> 

(規定)型のメンバについての情報を指定する。この情報には,識別情報,メンバの型,

仮引数などすべてのXML仕様の要素が含まれる。 

<!ATTLIST Member  

 MemberName NMTOKEN #REQUIRED 

 (規定)MemberNameは現在のメンバ名を指定する。 

background image

390 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

<!ELEMENT MemberOfLibrary (#PCDATA)> 

(規定)PCDATAはその型に含まれるライブラリの名前を示す。 

<!ELEMENT MemberSignature EMPTY> 

(規定)型の与えられたメンバの識別情報についてのテキストを(ソースコード書式で)

指定する。 

<!ATTLIST MemberSignature 

 Language CDATA #REQUIRED 

 (規定)CDATAは識別情報が記述されるプログラム言語を示す。全メンバはILAsm及

びC#の両方に記述される。 

 Value CDATA #REQUIRED 

(規定)CDATAは与えられた言語におけるメンバの識別情報のテキストを示す。 

<!ELEMENT MemberType (#PCDATA)> 

(規定)現在のメンバの種類を指定する。メンバの種類には,メソッド,特性,構築子,

フィールド,及びイベントがある。 

<!ELEMENT MemberValue (#PCDATA)> 

(規定)静的なリテラルフィールドの値を指定する。 

<!ELEMENT Members (Member*)> 

(規定)与えられた型のすべてのメンバの情報を指定する。 

<!ELEMENT PRE EMPTY> 

(描出及び書式設定)この要素は,描出目的だけに指定する。例えば,この後のテキスト

が前のテキストから離れていたほうが望ましい場合などに指定する。 

<!ELEMENT Parameter (Attributes?)> 

(規定)メソッド又は特性の特定の仮引数についての情報を指定する。 

<!ATTLIST Parameter 

     Name NMTOKEN #REQUIRED 

(規定)仮引数名を指定する。 

     Type CDATA #REQUIRED 

(規定)仮引数の型の完全限定名を指定する。 

<!ELEMENT Parameters (Parameter*)> 

(規定)与えられたメソッド又は与えられた特性の仮引数に関する情報を指定する。指定

された情報は,この要素の各Parameter要素に格納される。この要素は,メソッド又は

特性の各引数につき一つのParameter引数を格納する。 

<!ELEMENT ReturnType (#PCDATA)> 

(規定)現在のメンバが返す型の完全限定名を指定する。 

<!ELEMENT ReturnValue (ReturnType?)> 

(規定)メンバが返す型を指定する。ReturnTypeは構築子を除く全種類のメンバに対し

background image

391 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

て指定されなくてはならない。 

<!ELEMENT SPAN (#PCDATA | para | paramref | SPAN | see | block)*> 

(描出及び書式設定)この要素は,テキストを他のテキストと(復帰文字などによって)

分割したほうが望ましいことを指定する。仮引数,他の型,及びテキストのブロックへの

参照をSPAN要素に格納できる。 

<!ELEMENT ThreadingSafetyStatement (#PCDATA)> 

(規定)与えられた型に対するスレッド安全性に関する文を指定する。 

<!ELEMENT Type (TypeSignature+, MemberOfLibrary, AssemblyInfo, 

ThreadingSafetyStatement?, Docs, Base, Interfaces, Attributes?, 

Members, TypeExcluded)> 

(規定)与えられた型に対するすべての情報を指定する。 

<!ATTLIST Type 

 Name CDATA #REQUIRED 

 (参考)与えられた型の単純名(例えば,“System.String”ではなく“String”)を

指定する。 

 FullName CDATA #REQUIRED 

(規定)与えられた型の完全限定名を指定する。総称型に対しては,総称仮引数の名前の

綴りを含む。 

 FullNameSP CDATA #REQUIRED 

(参考)完全限定名中のʻ.ʼをʻ̲ʼに置き換えた完全限定名を指定する。 

<!ELEMENT TypeExcluded (#PCDATA)> 

(規定)PCDATAはʻ0ʼでなくてはならない。 

<!ELEMENT TypeSignature EMPTY> 

(規定)与えられた型の識別情報のためのテキストを(コード表現で)指定する。 

<!ATTLIST TypeSignature 

 Language CDATA #REQUIRED 

(規定)指定された型の識別情報が記述される言語を指定する。型すべての識別情報は,

ILAsm及びC#の両方に指定される。 

 Value CDATA #REQUIRED 

(規定)CDATAは指定された言語での型識別情報とする。 

<!ELEMENT Types (Type+)> 

(規定)ライブラリのすべての型についての情報を指定する。 

<!ATTLIST Types 

 Library NMTOKEN #REQUIRED 

(規定)すべての型が定義されたライブラリを指定する。このようなライブラリの例とし

て,“BCL”がある。 

background image

392 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

<!ELEMENT Altcompliant EMPTY> 

(参考)現在のCLS合致でないメソッドの代替として存在するCLS合致のメソッド呼出

しを指定する。例えば,この要素はSystem.IO.TextWriter.WriteLine(ulong)メソ

ッドに存在し,System.IO.TextWriter.WriteLine(long)が代替であることを示し

ている。このSystem.IO.TextWriter.WriteLine(long)はCLS合致メソッドである。 

<!ATTLIST Altcompliant 

 cref CDATA #REQUIRED 

(参考)代替のCLS合致メソッドに対する実際の文書へのリンクを指定する。 

[注記 このXML仕様では,CDATAはC#言語仕様の附属書Eに指定された文書化注

釈書式と一致する。] 

<!ELEMENT Altmember EMPTY> 

(参考)現在のメソッドの代替として存在する,同等なメンバの呼出しを指定する。この

要素は,演算子多重定義に使用される。 

<!ATTLIST Altmember 

 cref CDATA #REQUIRED 

(参考)代替のメンバ呼出しに対する実際の文書へのリンクを指定する。 

[注記 このXML仕様では,CDATAはC#言語仕様の附属書Eに指定された文書化注

釈書式と一致する。] 

<!ELEMENT block (#PCDATA | see | para | paramref | list | block | c 

| subscript | code | sup | pi)*> 

(描出及び書式設定)属性として指定されたtypeに従って,子が書式設定されることが

望ましいことを指定する。 

<!ATTLIST block 

 subset CDATA #REQUIRED 

(描出及び書式設定)この属性は,将来使用するために予約されているもので,現在は

ʻnoneʼの値だけをもつ。 

 type NMTOKEN #REQUIRED 

(描出及び書式設定)使用法,上書き,注釈,例,省略時,振る舞いのいずれかに続くブ

ロックの型を指定する。 

<!ELEMENT c (#PCDATA | para | paramref | code | see)*> 

(描出及び書式設定)テキストがコード見本の出力であることを指定する。 

<!ELEMENT code (#PCDATA)> 

(参考)テキストがコード見本であることを指定する。 

<!ATTLIST code 

 lang CDATA #IMPLIED 

(参考)コード見本のプログラム言語を指定する。このXML仕様では,見本の言語として

background image

393 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

C#を使用する。 

<!ELEMENT codelink EMPTY> 

(参考)他の見本からリンクが設定されるかもしれないコードの部分を指定する。 

注記 ここで指定されたXML書式は,こうしたリンクを作成する手段を提供しない。 

<!ATTLIST codelink 

 SampleID CDATA #REQUIRED 

(参考)SampleIDは,このコード見本に割り当てられた一意なIDを示す。 

 SnippetID CDATA #REQUIRED 

(参考)SnippetIDは,見本コード内のテキストの節に割り当てられた一意なIDを示す。 

<!ELEMENT description (#PCDATA | SPAN | paramref | para | see | c | 

permille | block | sub)*> 

(規定)一覧又は表の中にある与えられたterm要素に対する説明用のテキストを指定す

る。この要素は,表の中の欄見出し用テキストも指定する。 

<!ELEMENT example (#PCDATA | para | code | c | codelink | see)*> 

(参考)型又は与えられた型のメンバの使用例となるテキストを指定する。 

<!ELEMENT exception (#PCDATA | paramref | see | para | SPAN | block)*> 

(規定)他の方法で指定されない限り,型のメンバによって送出されなければならない例

外に対する情報となるテキストを指定する。この要素は,テキストだけ,又はブロックな

どの他の描出オプションを含むことがある。 

<!ATTLIST exception 

 cref CDATA #REQUIRED 

(描出及び書式設定)例外の文書へのリンクを指定する。 

注記 このXML仕様では,CDATAはC#言語標準の附属書Eに指定された文書化注釈

書式と一致する。 

<!ELEMENT i (#PCDATA)> 

(描出及び書式設定)テキストはイタリック体になることが望ましいことを指定する。 

<!ELEMENT item (term, description*)> 

(描出及び書式設定)一覧又は表内の特定の項目を指定する。 

<!ELEMENT list (listheader?, item*)> 

(描出及び書式設定)テキストが一覧形式で表示されることが望ましいことを指定する。 

<!ATTLIST list 

 type NMTOKEN #REQUIRED 

(描出及び書式設定)後に続くテキストが表される一覧の形式を指定する。このXML仕様

で許されている値はbullet,number及びtableとする。 

<!ELEMENT listheader (term, description+)> 

background image

394 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

(描出及び書式設定)与えられた一覧又は表内のすべての欄の見出しを指定する。 

<!ELEMENT onequarter EMPTY> 

(描出及び書式設定)¼のような書式で表示されるテキストを指定する。 

<!ELEMENT para (#PCDATA | see | block | paramref | c | onequarter | 

superscript | sup | permille | SPAN | list | pi | theta | sub)*> 

(描出及び書式設定)テキストがそれ自体の段落とみなされるものの一部であることを指

定する。 

<!ELEMENT param (#PCDATA | c | paramref | see | block | para | SPAN)*> 

(規定)仮引数の意味又は目的に関する情報を指定する。仮引数名及び文字記述は,この

要素と関連付けられる。 

<!ATTLIST param 

 name CDATA #REQUIRED 

(規定)記述されている仮引数の名前を指定する。 

<!ELEMENT paramref EMPTY> 

(描出及び書式設定)型のメンバの仮引数への参照を指定する。 

<!ATTLIST paramref 

 name CDATA #REQUIRED 

(描出及び書式設定)paramref要素が参照している仮引数の名前を指定する。 

<!ELEMENT permille EMPTY> 

(描出及び書式設定)現在のテキストがʻ‰ʼ記号として表示されることを表現する。 

<!ELEMENT permission (#PCDATA | see | paramref | para | block)*> 

(規定)型のメンバの呼出しに必要となるアクセス許可を指定する。これは,完全限定型

名及び補助テキストとして指定される。 

<!ATTLIST permission 

 cref CDATA #REQUIRED 

(描出及び書式設定)アクセス許可の文書へのリンクを指定する。 

注記 このXML仕様では,CDATAはC#言語標準の附属書Eに指定された文書化注釈

書式と一致する。 

<!ELEMENT pi EMPTY> 

(描出及び書式設定)現在のテキストがʻπʼ記号として表示されることを表現する。 

<!ELEMENT pre EMPTY> 

(描出及び書式設定)先行テキストと後続テキストとの間の区切りを指定する。 

<!ELEMENT remarks (#PCDATA | para | block | list | c | paramref | see 

| pre | SPAN | code | PRE)*> 

(規定)型又は型のメンバに関する,summaryによって渡された情報への追加情報を指定

する。 

background image

395 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

<!ELEMENT returns (#PCDATA | para | list | paramref | see)*> 

(規定)与えられた型メンバの返却値を記述するテキストを指定する。 

<!ELEMENT see EMPTY> 

(参考)他の型又はメンバへのリンクを指定する。 

<!ATTLIST see 

 cref CDATA #IMPLIED 

(参考)crefは,リンク先の型又はメンバの完全限定名を指定する。 

注記 このXML仕様では,CDATAはC#言語標準の附属書Eに指定された文書化注釈

書式と一致する。 

 langword CDATA #IMPLIED 

(参考)langwordは,リンク先が“null”などの言語にとらわれないキーワードである

ことを指定する。 

 qualify CDATA #IMPLIED 

(参考)qualifyは,リンクに指定された型又はメンバが完全限定として表示されなけれ

ばならないことを示す。この属性の値は,ʻtrueʼ又はʻfalseʼとなり,省略時の値は

ʻfalseʼである。 

<!ELEMENT sub (#PCDATA | paramref)*> 

(描出及び書式設定)テキストの現在の部分は下付きの記法となることを指定する。 

<!ELEMENT subscript EMPTY> 

(描出及び書式設定)テキストの現在の部分は下付きの記法となることを指定する。 

<!ATTLIST subscript 

 term CDATA #REQUIRED 

(描出及び書式設定)下付きで描出される値を指定する。 

<!ELEMENT summary (#PCDATA | para | see | block | list)*> 

(規定)与えられた型又は型のメンバの概要の説明を指定する。 

<!ELEMENT sup (#PCDATA | i | paramref)*> 

(描出及び書式設定)テキストの現在の部分は上付きの記法となることを指定する。 

<!ELEMENT superscript EMPTY> 

(描出及び書式設定)テキストの現在の部分は上付きの記法となることを指定する。 

<!ATTLIST superscript 

 term CDATA #REQUIRED 

(描出及び書式設定)上付きで描出される値を指定する。 

<!ELEMENT term (#PCDATA | block | see | paramref | para | c | sup | 

pi | theta)*> 

(描出及び書式設定)このテキストは一覧項目又は表の第1列の項目であることを指定す

る。 

background image

396 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

<!ELEMENT theta EMPTY> 

(描出及び書式設定)テキストがʻθʼのような書式で表示されることを指定する。 

<!ELEMENT threadsafe (para+)> 

(規定)現在の型のスレッド安全性の影響に関して,ThreadingSafetyStatementに

よって指定されたテキストへの追加詳細を記述したテキストを指定する。例えば,このテ

キストは,同期の観点から実装すべきことを記述する。 

<!ELEMENT value (#PCDATA | para | list | see)*> 

(規定)特性のsetメソッドに渡される“value”の記述情報を指定する。 

図1−XML DTD 

7.1.1 

オブジェクトとしての値型 

このXMLのメソッドの本文中の記述を通して,object型又はインタフェース型の引数が期待されて

いるにもかかわらず,値型の引数を渡すように記述されている場所がある。この場合,呼出し側は,呼出

しを行う前にこの値型をボックス化しなければならない。 

7.1.2 

例外 

XMLで定義されている型のメンバの多くには,例外条件が関連付けられている。メンバの定義で,他の

何らかの記述がなされていない限り,特定のメンバに記述された条件が発生した場合には,そのメンバに

対して定義されている例外が送出されなければならない。 

7.2 

XMLにおける識別情報の記法の問題点 

XMLで規定される型及びメンバには,それぞれILAsm及びC#の識別情報の対が存在する。これらは,

等価であること,並びに,各型及びメンバを正しく実装できるように十分な情報を提供することを意図し

たものである。各識別情報の対は,これらの識別情報に対する低水準及び高水準の概念を示している。た

だし,XMLで記述されているように,特定の識別情報の対が,同一の振る舞いを意図したものであっても,

そのメンバが必ずしも同等の方法で記述されるとは限らない。識別情報の記法における違いは,7.2.1〜

7.2.4で規定する。 

7.2.1 

直列化 

ILAsmの識別情報が示すように,標準ライブラリに存在する型の多くには,あらかじめ定義された属性

serializableが関連付けられている。この属性で指定された型は,その型の値の永続状態の一部として

直列化する。この規格は,規格適合処理系に対し,直列化(又はその逆の直列化解除)機能の提供を要求

するものではなく,これらの操作を実現する機構を指定するものでもない。 

次に,System.Stringを例に,XMLにおける識別情報がILAsmとC#とでどのように違うかを示す。 

[ILAsm] 

.class public sealed serializable String … 

[C#] 

public sealed class String … 

直列化の問題についてC#規格で取り扱うことはしないが,このライブラリ型をC#で記述した場合,コ

ンパイル時における,上記C#の宣言は,このクラスについて生成されるコードにはserializable属性

が含まれる,という意味になる。一部の実装は,この目的のために属性型 

System.SerializableAttributeを提供する。 

397 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

7.2.2 

委譲 

標準ライブラリには,多数の委譲型が含まれる。ただし,XMLで記録されているように,対応するILAsm

の識別情報は不完全である。例えば,System.EventHandlerに対応するILAsmの識別情報は,XML

で次のように定義される。 

.class public sealed serializable EventHandler extends System.Delegate 

{  

.method public hidebysig newslot virtual instance void Invoke(object 

   sender, class System.EventArgs e) } 

しかし,この型には,構築子,並びに,BeginInvoke及びEndInvokeという二つの省略可能な非同

期メソッドも存在する(第2章“委譲”参照)。System.EventHandlerのこの三つのメンバの識別情報

を次に示す。 

.method public hidebysig specialname rtspecialname void .ctor(object 

   'object', native int 'method') 

.method public hidebysig newslot virtual class System.IAsyncResult 

   BeginInvoke(object sender, class System.EventArgs e, class 

   System.AsyncCallback callback, object 'object') 

.method public hidebysig newslot virtual void EndInvoke( 

 class System.IAsyncResult result) 

他の標準の委譲型には,対応する構築子及びメソッドの対が存在するが,その識別情報は,XMLのILAsm

及び第2章“委譲”の情報から導出できる。 

別途記載のない限り,標準の委譲型は,二つの省略可能な非同期メソッドであるBeginInvoke及び

EndInvokeを提供する。 

7.2.3 

特性 

標準ライブラリには,特性をもつ型が多数含まれている。ただし,XMLで記録されているように,対応

するILAsmの識別情報は不完全である。例えば,読み書き可能なインスタンスの特性

System.Collections.ArrayList.Capacityを見ると,対応するILAsmの識別情報が,XMLでは次

のように定義されている。 

.property int32 Capacity { 

  public hidebysig virtual specialname int32 get̲Capacity() 

  public hidebysig virtual specialname void set̲Capacity(int32 value) 

ただし,これは,ILAsmの構文の省略形である。この特性の完全かつ正確な識別情報は,次のとおりで

ある。 

.property instance int32 Capacity() { 

  .get instance int32 ArrayList::get̲Capacity() 

  .set instance void ArrayList::set̲Capacity(int32) 

.method public hidebysig newslot specialname virtual instance int32 

 get̲Capacity() { … } 

.method public hidebysig newslot specialname virtual instance void 

background image

398 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

 set̲Capacity(int32 'value') { … } 

2番目の例として,読込み専用の静的特性であるSystem.DateTime.Nowを見ると,対応するILAsm

の識別情報が,XMLでは次のように定義されている。 

.property valuetype System.DateTime Now { 

  public hidebysig static specialname valuetype System.DateTime 

    get̲Now() 

ただし,この特性の完全かつ正確な識別情報は,次のとおりである。 

.property valuetype System.DateTime Now() { 

  .get valuetype System.DateTime DateTime::get̲Now() 

.method public hidebysig specialname static valuetype System.DateTime 

   get̲Now() { ... } 

XMLでは,その他すべての特性(添字指定された特性を含む)が,同様の省略形式で記述されている。 

7.2.4 

入れ子にされた型 

ある例外を除き,特定の型のXMLには,その型のすべてのメンバの定義が含まれる。その例外とは,

入れ子にされた型である。入れ子にされた型には,XMLに独自の定義が存在し,その名前は,入れ子にさ

れている型の名前によって限定される。型System.Collections.Generic.List<T>には,入れ子に

された型Enumeratorがある。XMLのBCLライブラリでは,これらの型がそれぞれ,List<T>及び

List<T>.Enumeratorという名前で規定されている。 

第5章 デバッグ情報交換形式 

可搬性CILDBファイル 

可搬性CILDBファイルは,CLIの生成側と使用側との間でデバッグ情報を交換するための標準的な手段

を提供するものである。第5章は,特に,局所変数の名前とソース行の対応など,メタデータだけではカ

バーできない部分を補うことを目的としている。 

1.1 

整数の符号化 

すべての整数は,下位バイト先行形式で格納される。ただし,識別情報は例外であり,第2章に規定さ

れた方法で符号化される。 

1.2 

CILDBヘッダ 

CILDBファイルの先頭には,72バイトのヘッダが存在する。その配置を次に示す。 

オフセット 

大きさ 

フィールド 

記述 

16 

Signature 

CILDB“̲ildb̲signature¥0”のMagic識別情報。 

16 

16 

GUID 

版のGUID。 

32 

UserEntryPoint 

入口点のMethodDefトークン。 

36 

CountOfMethods 

SymMethod表の行数。 

40 

CountOfScopes 

SymScopes表の行数。 

44 

CountOfVars 

SymVariable表の行数。 

48 

CountOfUsing 

SymUsing表の行数。 

52 

CountOfConstants 

SymConstant表の行数。 

56 

CountOfDocuments 

SymDocument表の行数。 

60 

CountOfSequencePoints 

SymSequencePoint表の行数。 

background image

399 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

64 

CountOfMiscBytes 

SymMiscヒープのバイト数。 

68 

CountOfStringBytes 

SymStringヒープのバイト数。 

1.2.1 

版のGUID 

版のGUIDは,次に示す16バイト列である。 

0x7F 

0x55 

0xE7 

0xF1 

0x3C 

0x42 

0x17 

0x41 

0x8D 

0xA9 

0xC7 

0xA3 

0xCD 

0x98 

0x8D 

0xF1 

1.3 

表及びヒープ 

CILDBヘッダの直後には,各種の表及びヒープが,次の順序で続く。 

1) SymConstant 

2) SymMethod 

3) SymScopes 

4) SymVariable 

5) SymUsing 

6) SymSequencePoint 

7) SymDocument 

8) SymMisc 

9) SymString 

一部の表には,CILオフセットが含まれる。これらのオフセットはバイト単位であり,先頭の命令のオ

フセットはゼロである。オフセットがCIL命令の先頭と一致しなくてもよい。例えば,バイト範囲の末尾

を示すオフセットが,しばしば,命令の最終バイトを指す場合がある。長さもバイト単位で表される。 

上記の表3)〜7)のそれぞれにおいて,同じメソッドに属している行は,その親の表内で連続していなけ

ればならない。 

1.3.1 

SymConstant表 

SymConstant表の各行は,次のように定数を表す。 

オフセット 

大きさ 

フィールド 

記述 

Scope 

親の有効範囲の添字。 

Name 

SymStringヒープ内の名前の添字。 

Signature 

SymMiscヒープ内の識別情報の添字。 

12 

SignatureSize 

識別情報の長さ。 

16 

Value 

SymMiscヒープ内の値の添字。 

20 

ValueSize 

値の長さ。 

定数の値は,長さの接頭辞が存在しない点を除けば,第2章に記載されているConstantメタデータ表の

Value列のBlobと同じように符号化される。 

1.3.2 

SymDocument表 

SymDocumentの各行は,次のようにソース文書を表す。文書は間接的に(対応するURLで)参照する

ことも,SymMiscヒープの一部として直接CILDBファイルに組み込むこともできる。ここで引用された

GUID値は,この規格では定義されない。単に必要な領域が予約されているだけである。 

オフセット 

大きさ 

フィールド 

記述 

16 

Language 

言語のGUID。 

16 

16 

LanguageVendor 

言語ベンダのGUID。 

32 

16 

DocumentType 

文書の種類のGUID。 

48 

16 

AlgorithmId 

チェックサムアルゴリズムのGUID。チェックサムがない場合
は0。 

background image

400 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

64 

CheckSumSize 

チェックサムの大きさ。チェックサムがない場合は0。 

68 

CheckSumEntry 

SymMiscヒープにおけるチェックサムの添字。チェックサムが
ない場合は0。 

72 

SourceSize 

SymMiscヒープにおけるソースの大きさ。ソース文書がファイ
ルに直接組み込まれていない場合は0。 

76 

SourceEntry 

SymMiscヒープにおけるソースの添字。ソース文書がファイル
に直接組み込まれていない場合は0。 

80 

UrlEntry 

SymStringヒープ内の文書URLの添字。 

1.3.3 

SymMethod表 

SymMethod表の各行の形式を次に示す。 

オフセット 

大きさ 

フィールド 

記述 

MethodToken 

MethodDefメタデータトークン。 

Scopes 

SymScope表の[Start,Stop)区間。 

12 

Vars 

SymVariable表の[Start,Stop)区間。 

20 

Using 

SymUsing表の[Start,Stop)区間。 

28 

Constant 

SymConstant表の[Start,Stop)区間。 

36 

Documents 

SymDocument表の[Start,Stop)区間。 

44 

SequencePoints 

SymSequencePoint表の[Start,Stop)区間。 

各[Start,Stop)区間は,二つの4バイト整数として表される。一つ目の整数は,関連する表の先頭行の添

字で,二つ目の整数は,関連する表の最後の行の添字に1を加えたものである。 

SymMethod表の行は,MethodTokenフィールドの昇順に並べ替えられる。各メソッドの行数は,最大で

1行である。 

1.3.4 

SymSequencePoint表 

SymSequencePoint表の各行は,次のように副作用完了点を表す。 

オフセット 

大きさ 

フィールド 

記述 

Offset 

副作用完了点のCILオフセット。 

StartLine 

ソース文書の開始行。 

StartColumn 

開始欄。指定されていない場合は0。 

12 

EndLine 

ソース文書の終了行。指定されていない場合は0。 

16 

EndColumn 

終了欄。指定されていない場合は0。 

20 

Doc 

SymStringヒープ内のソース文書の添字。 

EndLine及びEndColumnは,副作用完了点に関連付けられた最終バイト位置の“一つ後の”欄を指定す

る。つまり,半開区間[start,end)の終端を指定する。 

同じメソッドに属するSymSequencePointの行は,連続していなければならず,かつ,オフセットの昇順

で並べられていなければならない。 

1.3.5 

SymScope表 

SymScope表の各行は,次のように有効範囲を表す。 

オフセット 

大きさ 

フィールド 

記述 

Parent 

親SymScope行の添字。有効範囲に親が存在しない場合は1。 

StartOffset 

有効範囲内の先頭バイトのCILオフセット。 

EndOffset 

有効範囲内の最終バイトのCILオフセット。 

12 

HasChildren 

有効範囲に子の有効範囲が存在する場合は1。そうでなければ
0。 

16 

HasVars 

有効範囲に変数が存在する場合は1。そうでなければ0。 

メソッドに属する有効範囲は,次の制約を満たしたツリーを形成していなければならない。 

background image

401 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

− 親の有効範囲が,子の有効範囲に先行する。 

− 子の有効範囲のStartOffset及びEndOffsetが,対応する親の有効範囲によって指定されたオフセットの

(両端を含んだ)区間内に存在する。 

1.3.6 

SymVariable表 

SymVariable表の各行は,局所変数を表す。 

オフセット 

大きさ 

フィールド 

記述 

Scope 

親の有効範囲の添字。 

Name 

SymStringヒープ内の変数名の添字。 

Attributes 

変数を表すフラグ(以下参照)。 

12 

Signature 

SymMiscヒープ内の識別情報の添字。 

16 

SignatureSize 

識別情報の長さ。 

20 

AddressKind 

常に1。 

24 

Address1 

局所変数値。 

28 

Address2 

常に0。 

32 

Address3 

常に0。 

36 

StartOffset 

変数が最初に可視状態になる位置のCILオフセット。 

40 

EndOffset 

変数が最後に可視状態になる位置のCILオフセット。 

44 

Sequence 

常に0。 

48 

IsParam 

常に0。 

52 

IsHidden 

変数をデバッガから隠ぺいする場合は1。そうでなければ0。 

Attributesの最下位ビットは,変数が利用者によって生成されたものか(0),又は,コンパイラによって

生成されたものか(1)を示す。その他のビットは予約済みであり,ゼロに設定されている必要がある。 

仮引数はメタデータによって完全に規定されるため,SymVariable表には出現しない。 

1.3.7 

SymUsing表 

SymUsing表の各行は,次のように名前空間のインポートを表す。 

オフセット 

大きさ 

フィールド 

記述 

Scope 

親の有効範囲の添字。 

Namespace 

SymStringヒープ内の名前空間の添字。 

1.3.8 

SymMiscヒープ 

SymMiscヒープは,各種のバイト列(識別情報,チェックサムなど)を保持する。 

1.3.9 

SymStringヒープ 

SymStringヒープ内のバイトストリームは,#Stringsヒープと同じ形式をもつ(第2章参照)。 

1.4 

識別情報 

変数及び定数の識別情報は,SymMiscヒープへの添字及び識別情報の大きさとして符号化される。バイ

トの値は,FieldSig(第2章参照)の値と似ており,変数がフィールドではなくても,接頭辞FIELD(0x6)

を含んでいる。識別情報の長さは表に符号化されるため,SymMiscヒープには含まれない。例えば,型int32

は,“0x06 0x08”として符号化される。 

402 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

第6章 附属書 

附属書A 

(参考) 
有効範囲 

附属書Aは,この附属書である。 

附属書Bには,CILアセンブリ言語(ILAsm)で記述された多数の見本プログラムが収録されている。 

附属書Cには,アセンブラの特定の実装に関する情報が含まれており,そのアセンブラは第2章で説明

した構文の機能に関するスーパーセットが提供される。また,CIL命令集合の機械可読な説明も提供する。

これを用いて,このアセンブラ,及びCILを操作する他のツールによって利用される文法の部分を入手す

ることができる。 

附属書Dには,第4章で説明したライブラリの設計に利用される一連のガイドラインが含まれる。こう

した規則は,複数言語間で共有されるAPIの設計時にその有効性が証明されたため,提供されるようにな

った。また,これらの規則は,規格化されたライブラリと境目なく統合できるよう,追加機能の提供者に

対するAPIのガイドラインとしての役割も果たす。 

附属書Eには,CLIを実装する場合における自由裁量の範囲について,実装者が関心を寄せる情報が含

まれる。 

附属書Fには,ゆるい障害処理を行う実装者に有用な情報を含む。 

附属書Gでは,並列ライブラリを用いて記述された,幾つかの完全な例を示す。 

403 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

附属書B 

(参考) 

見本プログラム 

注記 附属書Bは参考情報だけを示す。 

この附属書では,ILAsmを使って記述される完全な例を幾つか示す。 

B.1 

相互再帰的プログラム(末尾呼出しを利用) 

次に,末尾呼出しを利用する相互再帰的プログラムの見本を示す。次に示すメソッドは,数値が偶数か

奇数かを判定する。 

例 

.assembly extern mscorlib { } 

.assembly test.exe { } 

.class EvenOdd 

{ .method private static bool IsEven(int32 N) cil managed 

  { .maxstack   2 

    ldarg.0             // N 

    ldc.i4.0 

    bne.un      NonZero 

    ldc.i4.1 

    ret 

NonZero: 

    ldarg.0 

    ldc.i4.1 

    sub 

    tail. 

    call bool EvenOdd::IsOdd(int32) 

    ret 

  } // end of method ʻEvenOdd::IsEvenʼ 

  .method private static bool IsOdd(int32 N) cil managed 

  { .maxstack   2 

    // Demonstrates use of argument names and labels 

    // Notice that the assembler does not convert these 

    // automatically to their short versions 

    ldarg       N 

    ldc.i4.0 

    bne.un      NonZero 

    ldc.i4.0 

404 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

    ret 

NonZero: 

    ldarg       N 

    ldc.i4.1 

    sub 

    tail. 

    call bool EvenOdd::IsEven(int32) 

    ret 

  } // end of method ʻEvenOdd::IsOddʼ 

  .method public static void Test(int32 N) cil managed 

  { .maxstack   1 

    ldarg       N 

    call        void [mscorlib]System.Console::Write(int32) 

    ldstr       " is " 

    call        void [mscorlib]System.Console::Write(string) 

    ldarg       N 

    call        bool EvenOdd::IsEven(int32) 

    brfalse     LoadOdd 

    ldstr       "even" 

Print: 

    call        void [mscorlib]System.Console::WriteLine(string) 

    ret 

LoadOdd: 

    ldstr       "odd" 

    br          Print 

  } // end of method ʻEvenOdd::Testʼ  

} // end of class ʻEvenOddʼ 

//Global method 

.method public static void main() cil managed 

{ .entrypoint 

  .maxstack     1 

  ldc.i4.5 

  call          void EvenOdd::Test(int32) 

  ldc.i4.2 

  call          void EvenOdd::Test(int32) 

  ldc.i4        100 

  call          void EvenOdd::Test(int32) 

405 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

  ldc.i4        1000001 

  call          void EvenOdd::Test(int32) 

  ret 

} // end of global method ʻmainʼ 

B.2 

値型の利用 

次のプログラムは,値型を利用した有理数の実装方法を示す。 

例 

.assembly extern mscorlib { } 

.assembly rational.exe { } 

.class private sealed Rational extends [mscorlib]System.ValueType 

                             implements [mscorlib]System.IComparable 

{ .field public int32 Numerator 

  .field public int32 Denominator 

  .method virtual public int32 CompareTo(object o) 

  // Implements IComparable::CompareTo(Object) 

  { ldarg.0     // ʻthisʼ as a managed pointer 

    ldfld int32 value class Rational::Numerator 

    ldarg.1     // ʻoʼ as an object 

    unbox value class Rational 

    ldfld int32 value class Rational::Numerator 

    beq.s TryDenom 

    ldc.i4.0 

    ret 

TryDenom: 

    ldarg.0     // ʻthisʼ as a managed pointer 

    ldfld int32 value class Rational::Denominator 

    ldarg.1     // ʻoʼ as an object 

    unbox value class Rational 

    ldfld int32 class Rational::Denominator 

    ceq 

    ret 

  } 

  .method virtual public string ToString() 

  // Implements Object::ToString 

  { .locals init (class [mscorlib]System.Text.StringBuilder SB, 

                  string S, object N, object D) 

    newobj void [mscorlib]System.Text.StringBuilder::.ctor() 

406 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

    stloc.s SB 

    ldstr "The value is: {0}/{1}" 

    stloc.s S 

    ldarg.0     // Managed pointer to self 

    dup 

    ldfld int32 value class Rational::Numerator 

    box [mscorlib]System.Int32 

    stloc.s N 

    ldfld int32 value class Rational::Denominator 

    box [mscorlib]System.Int32 

    stloc.s D 

    ldloc.s SB 

    ldloc.s S 

    ldloc.s N 

    ldloc.s D 

    call instance class [mscorlib]System.Text.StringBuilder 

      [mscorlib]System.Text.StringBuilder::AppendFormat(string, 

       

object, object) 

    callvirt instance string [mscorlib]System.Object::ToString() 

    ret 

  } 

  .method public value class Rational Mul(value class Rational) 

  { 

    .locals init (value class Rational Result) 

    ldloca.s Result 

    dup 

    ldarg.0     // ʻthisʼ 

    ldfld int32 value class Rational::Numerator 

    ldarga.s    1     // arg 

    ldfld int32 value class Rational::Numerator 

    mul 

    stfld int32 value class Rational::Numerator 

    ldarg.0     // this 

    ldfld int32 value class Rational::Denominator 

    ldarga.s    1     // arg 

    ldfld int32 value class Rational::Denominator 

    mul 

    stfld int32 value class Rational::Denominator 

    ldloc.s Result 

    ret 

407 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

  } 

.method static void main() 

  .entrypoint 

  .locals init (value class Rational Half, 

                value class Rational Third, 

                value class Rational Temporary, 

                object H, object T) 

  // Initialize Half, Third, H, and T 

  ldloca.s Half 

  dup 

  ldc.i4.1 

  stfld int32 value class Rational::Numerator 

  ldc.i4.2 

  stfld  int32 value class Rational::Denominator 

  ldloca.s Third 

  dup 

  ldc.i4.1 

  stfld int32 value class Rational::Numerator 

  ldc.i4.3 

  stfld int32 value class Rational::Denominator 

  ldloc.s Half 

  box value class Rational 

  stloc.s H 

  ldloc.s Third 

  box value class Rational 

  stloc.s T 

  // WriteLine(H.IComparable::CompareTo(H)) 

  // Call CompareTo via interface using boxed instance 

  ldloc H 

  dup 

  callvirt int32 [mscorlib]System.IComparable::CompareTo(object) 

  call void [mscorlib]System.Console::WriteLine(bool) 

  // WriteLine(Half.CompareTo(T)) 

  // Call CompareTo via value type directly 

  ldloca.s Half 

  ldloc T 

  call instance int32 

  value class Rational::CompareTo(object) 

408 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

  call void [mscorlib]System.Console::WriteLine(bool) 

  // WriteLine(Half.ToString()) 

  // Call virtual method via value type directly 

  ldloca.s Half 

  call instance string class Rational::ToString() 

  call void [mscorlib]System.Console::WriteLine(string) 

  // WriteLine(T.ToString) 

  // Call virtual method inherited from Object, via boxed instance 

  ldloc T 

  callvirt string [mscorlib]System.Object::ToString() 

  call void [mscorlib]System.Console::WriteLine(string) 

  // WriteLine((Half.Mul(T)).ToString()) 

  // Mul is called on two value types, returning a value type 

  // ToString is then called directly on that value type 

  // Note that we are required to introduce a temporary variable 

  //   since the call to ToString requires 

  //   a managed pointer (address) 

  ldloca.s Half 

  ldloc.s Third 

  call instance value class Rational 

         Rational::Mul(value class Rational) 

  stloc.s Temporary 

  ldloca.s Temporary 

  call instance string Rational::ToString() 

  call void [mscorlib]System.Console::WriteLine(string) 

  ret 

B.3 

カスタム属性 

注記 ここから例とする。 

例 

B.3では,前述の文法及び規則を明確にするため,カスタム属性の使用法について各種の例を

示す。例はC#で記述したものである。それぞれ,“App”という名前のクラスに適用された一つ

以上の属性の集団を示している。カスタム属性blobの16進数及び“翻訳”は,注釈として示す。

次の省略形が使用されている。 

− FIELD = ELEMENT̲TYPE̲FIELD 

− PROPERTY = 0x54 

− STRING = ELEMENT̲TYPE̲STRING 

− SZARRAY = ELEMENT̲TYPE̲SZARRAY 

− U1 = ELEMENT̲TYPE̲U1 

409 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

− I4 = ELEMENT̲TYPE̲I4 

− OBJECT = 0x51 

// 

******************************************************************

************** 

// CustomSimple.cs 

using System; 

[AttributeUsage(AttributeTargets.Class, AllowMultiple=true)] 

class B : Attribute { public B(int i, ushort u) {} }  

[B(7,9)]    // 01 00          // Prolog 

            // 07 00 00 00    // 0x00000007 

            // 09 00          // 0x0009 

            // 00 00          // NumNamed 

class App { static void Main() {} } 

// 

******************************************************************

************** 

// CustomString.cs 

using System; 

[AttributeUsage(AttributeTargets.Class, AllowMultiple=true)] 

class A : Attribute {  

   public  string field;        // field 

   private string back;         // backing field for property 

   public  string prop {        // property 

      get { return back;  }  

      set { back = value; } 

   } 

   public  A(string x) {}       // ctor 

[A(null)]   // 01 00           

// Prolog 

            // FF              

// null 

            // 00 00           

// NumNamed 

[A("")]     // 01 00           

// Prolog 

            // 00              

// zero-length string 

            // 00 00           

// NumNamed 

410 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

[A("ab",field="cd",prop="123")]  // 01 00             // Prolog 

                                 // 02 61 62          // "ab" 

                                 // 02 00             // NumNamed 

                                 // 53 0e             // FIELD, STRING 

                                 // 05 66 69 65 6c 64 // "field" as 

counted-UTF8 

                                 // 02 63 64          // "cd" as counted-UTF8 

                                 // 54 0e             // PROPERTY, STRING 

                                 // 04 70 72 6f 70    // "prop" as 

counted-UTF8 

                                 // 03 31 32 33       // "123" as counted-UTF8 

class App { static void Main() {} } 

// 

******************************************************************

************** 

// CustomType.cs 

using System; 

[AttributeUsage(AttributeTargets.Class, AllowMultiple=true)] 

class C : Attribute { 

   public C(Type t) {} 

[C(typeof(C))]  

// 01 00                                              // Prolog 

// 01 43                                              // "C" as counted-UTF8 

// 00 00                                              // NumNamed 

[C(typeof(string))]   

// 01 00                                              // Prolog 

// 0d 53 79 73 74 65 6d 2e 53 74 72 69 6e 67          // "System.String" 

as counted-UTF8 

// 00 00                                              // NumNamed 

[C(typeof(System.Windows.Forms.Button))] 

// 01 00                                              // Prolog 

// 76 53 79 73 74 65 6d 2e 57 69 6e 64 6f 77          // "System.Window 

// 73 2e 46 6f 72 6d 73 2e 42 75 74 74 6f 6e 2c 53    // s.Forms.Button,S 

// 79 73 74 65 6d 2e 57 69 6e 64 6f 77 73 2e 46 6f    // ystem.Windows.Fo 

// 72 6d 73 2c 20 56 65 72 73 69 6f 6e 3d 32 2e 30    // rms, Version=2.0 

// 2e 33 36 30 30 2e 30 2c 20 43 75 6c 74 75 72 65    // .3600.0, Culture 

411 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

// 3d 6e 65 75 74 72 61 6c 2c 20 50 75 62 6c 69 63    // =neutral, Public 

// 4b 65 79 54 6f 6b 65 6e 3d 62 37 37 61 35 63 35    // KeyToken=b77a5c5 

// 36 31 39 33 34 65 30 38 39 00 00                   // 61934e089" 

// 00 00                                              // NumNamed 

class App { static void Main() {} } 

各種の型がどのように“文字列化”されているかに注目されたい。型が局所アセンブリ内又は

mscorlib内で定義されている場合,必要なのは,その完全名だけである。型が異なるアセンブリ

で定義されている場合は,Version,Culture及びPublicKeyTokenを含む,その完全限定アセンブリ

名が必要となる(省略時以外)。 

// 

******************************************************************

************** 

// CustomByteArray.cs 

using System; 

class D : Attribute {  

   public  byte[] field;                             // field 

   private byte[] back;                              // backing field for 

property 

   public  byte[] prop {                             // property 

      get { return back;  }  

      set { back = value; } 

   } 

   public D(params byte[] bs) {}                     // ctor 

[D(1,2, field=new byte[]{3,4},prop=new byte[]{5})] 

// 01 00                                             // Prolog 

// 02 00 00 00                                       // NumElem 

// 01 02                                             // 1,2 

// 02 00                                             // NumNamed 

// 53 1d 05                                          // FIELD, SZARRAY, U1 

// 05 66 69 65 6c 64                                 // "field" as counted-UTF8 

// 02 00 00 00                                       // NumElem = 0x00000002 

// 03 04                                             // 3,4 

// 54 1d 05                                          // PROPERTY, SZARRAY, 

U1 

// 04 70 72 6f 70                                    // "prop" as counted-UTF8 

// 01 00 00 00                                       // NumElem = 0x00000001 

// 05                                                // 5 

412 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

class App { static void Main() {} } 

// 

******************************************************************

************** 

// CustomBoxedValuetype.cs 

using System; 

[AttributeUsage(AttributeTargets.Class, AllowMultiple=true)] 

class E : Attribute { 

   public object obj;                           // field called "obj" 

   public object o {                            // property called "o" 

      get { return o; } 

      set { o = value; } 

   } 

   public E() {}                                // default ctor 

   public E(object x) {} 

[E(42)]                                         // boxed 42 

// 01 00                                        // Prolog 

// 08                                           // I4 

// 2a 00 00 00                                  // 0x0000002A 

// 00 00                                        // NumNamed 

[E(obj=7)]                                      // named field 

// 01 00                                        // Prolog 

// 01 00                                        // NumNamed 

// 53 51                                        // FIELD, OBJECT 

// 03 6f 62 6a                                  // "obj" as counted-UTF8 

// 08                                           // I4 

// 07 00 00 00                                  // 0x00000007 

[E(o=0xEE)]                                     // named property 

// 01 00                                        // Prolog 

// 01 00                                        // NumNamed 

// 54 51                                        // PROPERTY, OBJECT 

// 01 6f                                        // "o" as counted-UTF8 

// 08                                           // I4 

// ee 00 00 00                                  // 0x000000EE 

class App { static void Main() {} } 

413 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

この例は,構築子でSystem.Objectを名前付きフィールドとして,及び名前付き特性として

受け取るカスタム属性のblobを構築する方法を示したものである。いずれの場合も,渡される実

引数はint32であり,C#コンパイラによって自動的にボックス化される。 

OBJECT = 0x51バイトであることに注目されたい。これは,System.Object型の“名前付き”

のフィールド又は特性用に生成される。 

// 

******************************************************************

************** 

// CustomShortArray.cs 

using System; 

[AttributeUsage(AttributeTargets.Class, AllowMultiple=true)] 

class F : Attribute {  

   public F(params short[] cs) {}    // ctor 

//[F()] 

// 01 00                            // Prolog 

// 00 00 00 00                      // NumElem 

// 00 00                            // NumNamed 

//[F(null)] 

// 01 00                            // Prolog 

// ff ff ff ff                      // NumElem = -1 => null 

// 00 00                            // NumNamed 

[F(1,2)] 

// 01 00                            // Prolog 

// 02 00 00 00                      // NumElem 

// 01 00 02 00                      // 0x0001, 0x0002 

// 00 00                            // NumNamed 

class App { static void Main() {} } 

注記 例終わり 

B.4 

総称型のコード及びメタデータ 

以降では,単純な電話帳クラスの部分的な実装を示す。まず,ILAsmで記述されたソースを示した後,

それをC#で記述した同等の(より短い)コードを示す。さらに,このコードで生成されるメタデータも示

す。 

B.4.1 ILAsm版 

.assembly extern mscorlib {} 

414 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

.assembly Phone {} 

.class private Phonè2<([mscorlib]System.Object) K, 

([mscorlib]System.Object) V>  

    extends  [mscorlib]System.Object { 

   .field private int32 hi 

   .field private !0[]  keys 

   .field private !1[]  vals 

   .method public instance void Add(!0 k, !1 v) { 

      .maxstack  4 

      .locals init (int32 temp) 

      ldarg.0 

      ldfld      !0[] class Phonè2<!0,!1>::keys 

      ldarg.0 

      dup 

      ldfld      int32 class Phonè2<!0,!1>::hi 

      ldc.i4.1 

      add 

      dup 

      stloc.0 

      stfld      int32 class Phonè2<!0,!1>::hi 

      ldloc.0 

      ldarg.1 

      stelem     !0 

      ldarg.0 

      ldfld      !1[] class Phonè2<!0,!1>::vals 

      ldarg.0 

      ldfld      int32 class Phonè2<!0,!1>::hi 

      ldarg.2 

      stelem     !1 

      ret 

   }  // end of Method Add 

}  // end of class Phone 

.class App extends [mscorlib]System.Object { 

   .method static void Main() { 

      .entrypoint 

      .maxstack  3 

      .locals init (class Phonè2<string,int32> temp) 

      newobj     instance void class 

  

Phonè2<string,int32>::.ctor() 

      stloc.0 

415 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

      ldloc.0 

      ldstr      "Jim" 

      ldc.i4.7 

      callvirt   instance void class 

  

Phonè2<string,int32>::Add(!0, !1) 

      ret 

   }  // end of method Main 

}  // end of class App 

B.4.2 C#版 

using System; 

class Phone<K,V> {  

   private int hi = -1; 

   private K[] keys; 

   private V[] vals; 

   public Phone() { keys = new K[10]; vals = new V[10]; } 

   public void Add(K k, V v) { keys[++hi] = k; vals[hi] = v; } 

class App {  

   static void AddOne<KK,VV>(Phone<KK,VV> phone, KK kk, VV vv) { 

      phone.Add(kk, vv); 

   } 

   static void Main() { 

      Phone<string, int> d = new Phone<string, int>(); 

      d.Add("Jim", 7); 

      AddOne(d, "Joe", 8); 

   } 

B.4.3 メタデータ 

第2章23.2.12に規定されているように,現在,Type非終端記号には,総称型のインスタンス化のため

の生成規則が追加されている。その例を次に示す。 

Type ::= . . . 

     | GENERICINST (CLASS | VALUETYPE) TypeDefOrRefEncoded GenArgCount 

Type * 

この生成規則に従い,上記Phone<string,int>のインスタンス化は次のように符号化される。 

0x15  ELEMENT̲TYPE̲GENERICINST 

0x12  ELEMENT̲TYPE̲CLASS 

0x08  TypeDefOrRef coded index for class “Phone<K,V>” 

0x02  GenArgCount = 2 

0x0E     ELEMENT̲TYPE̲STRING 

0x08     ELEMENT̲TYPE̲I4 

416 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

同様に,フィールドvalsの識別情報は,次のように符号化される。 

0x06  FIELD 

0x1D  ELEMENT̲TYPE̲SZARRAY 

0x13  ELEMENT̲TYPE̲VAR 

0x01  1, representing generic argument number 1 (i.e., “V”) 

同様に,(若干不自然だが)静的メソッドAddOneの識別情報は,次のように符号化される。 

0x10  IMAGE̲CEE̲CS̲CALLCONV̲GENERIC 

0x02  GenParamCount = 2 (2 generic parameters for this method: KK and 

VV 

0x03  ParamCount = 3 (phone, kk and vv) 

0x01  RetType = ELEMENT̲TYPE̲VOID 

0x15  Param-0:  ELEMENT̲TYPE̲GENERICINST 

0x12            ELEMENT̲TYPE̲CLASS 

0x08            TypeDefOrRef coded index for class “Phone<KK,VV>” 

0x02            GenArgCount = 2  

0x1e               ELEMENT̲TYPE̲MVAR 

0x00               !!0 (KK in AddOne<KK,VV>) 

0x1e               ELEMENT̲TYPE̲MVAR 

0x01               !!1 (VV in AddOne<KK,VV>) 

0x1e  Param-1   ELEMENT̲TYPE̲MVAR 

0x00            !!0 (KK in AddOne<KK,VV>) 

0x1e  Param-2   ELEMENT̲TYPE̲MVAR 

0x01            !!1 (VV in AddOne<KK,VV>) 

上の例では,メソッドの三つの仮引数及びPhoneの二つの総称仮引数に対するループを分かりやすく示

すためにインデントを用いている点に注意されたい。 

background image

417 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

附属書C 
(参考) 

CILアセンブラの実装 

注記 附属書Cは参考情報だけを示す。 

この附属書は,ilasmと呼ばれる,CIL向けの特定のアセンブラについて説明する。このアセンブラは,

第2章で規定として定義した構文のスーパーセットを提供し,第3章で規定したCIL命令の具体的な構文

を提供する。 

この特定のアセンブラに関する情報に関心をもたない場合でも,C.1及びC.3の情報を参照することを

お勧めする。前者は,CIL命令を部分的に説明する機械可読なファイル(C又はC++プリプロセッサに入

力することが可能。)である。CILを処理する多様なツールによって利用されるテーブルを生成するのに用

いることができる。後者には,他で説明されることのない,CIL命令の具体的な構文が含まれる。 

C.1 ILAsmのキーワード 

この節では,ilasmによって利用されるキーワードの全リストを示す。プログラム内の簡単な識別子とし

てこうしたキーワードのいずれかを利用することを利用者が望む場合,適切なエスケープ記号(文法で指

定した一重引用符又は二重引用符。)を利用する。このアセンブラは大文字と小文字とを識別する。 

#line 

.addon 

.assembly 

.cctor 

.class 

.corflags 

.ctor 

.custom 

.data 

.emitbyte 

.entrypoint 

.event 

.export 

.field 

.file 

.fire 

.get 

.hash 

.imagebase 

.import 

.language 

.line 

.locale 

.localized 

.locals 

.manifestres 

.maxstack 

.method 

.module 

.mresource 

.namespace 

.other 

.override 

.pack 

.param 

.pdirect 

.permission 

.permissionset 

.property 

.publickey 

.publickeytoken 

.removeon 

.set 

.size 

.subsystem 

.try 

.ver 

.vtable 

.vtentry 

.vtfixup 

.zeroinit 

^THE̲END^ 

abstract 

add 

add.ovf 

add.ovf.un 

algorithm 

alignment 

and 

ansi 

any 

arglist 

array 

as 

assembly 

assert 

at 

auto 

autochar 

beforefieldinit 

beq 

beq.s 

bge 

bge.s 

bge.un 

bge.un.s 

bgt 

bgt.s 

bgt.un 

bgt.un.s 

ble 

ble.s 

ble.un 

ble.un.s 

blob 

blob̲object 

blt 

blt.s 

blt.un 

blt.un.s 

bne.un 

bne.un.s 

bool 

box 

br 

br.s 

break 

brfalse 

brfalse.s 

brinst 

brinst.s 

brnull 

brnull.s 

brtrue 

background image

418 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

brtrue.s 

brzero 

brzero.s 

bstr 

bytearray 

byvalstr 

call 

calli 

callmostderived 

callvirt 

carray 

castclass 

catch 

cdecl 

ceq 

cf 

cgt 

cgt.un 

char 

cil 

ckfinite 

class 

clsid 

clt 

clt.un 

const 

conv.i 

conv.i1 

conv.i2 

conv.i4 

conv.i8 

conv.ovf.i 

conv.ovf.i.un 

conv.ovf.i1 

conv.ovf.i1.un 

conv.ovf.i2 

conv.ovf.i2.un 

conv.ovf.i4 

conv.ovf.i4.un 

conv.ovf.i8 

conv.ovf.i8.un 

conv.ovf.u 

conv.ovf.u.un 

conv.ovf.u1 

conv.ovf.u1.un 

conv.ovf.u2 

conv.ovf.u2.un 

conv.ovf.u4 

conv.ovf.u4.un 

conv.ovf.u8 

conv.ovf.u8.un 

conv.r.un 

conv.r4 

conv.r8 

conv.u 

conv.u1 

conv.u2 

conv.u4 

conv.u8 

cpblk 

cpobj 

currency 

custom 

date 

decimal 

default 

default 

demand 

deny 

div 

div.un 

dup 

endfault 

endfilter 

endfinally 

endmac 

enum 

error 

explicit 

extends 

extern 

false 

famandassem 

family 

famorassem 

fastcall 

fastcall 

fault 

field 

filetime 

filter 

final 

finally 

fixed 

float 

float32 

float64 

forwardref 

fromunmanaged 

handler 

hidebysig 

hresult 

idispatch 

il 

illegal 

implements 

implicitcom 

implicitres 

import 

in 

inheritcheck 

init 

initblk 

initobj 

initonly 

instance 

int 

int16 

int32 

int64 

int8 

interface 

internalcall 

isinst 

iunknown 

jmp 

lasterr 

lcid 

ldarg 

ldarg.0 

ldarg.1 

ldarg.2 

ldarg.3 

ldarg.s 

ldarga 

ldarga.s 

ldc.i4 

ldc.i4.0 

ldc.i4.1 

ldc.i4.2 

ldc.i4.3 

ldc.i4.4 

ldc.i4.5 

ldc.i4.6 

ldc.i4.7 

ldc.i4.8 

ldc.i4.M1 

ldc.i4.m1 

ldc.i4.s 

ldc.i8 

ldc.r4 

ldc.r8 

ldelem.i 

ldelem.i1 

ldelem.i2 

ldelem.i4 

ldelem.i8 

ldelem.r4 

ldelem.r8 

ldelem.ref 

ldelem.u1 

ldelem.u2 

ldelem.u4 

ldelem.u8 

ldelema 

ldfld 

ldflda 

ldftn 

ldind.i 

ldind.i1 

ldind.i2 

ldind.i4 

ldind.i8 

ldind.r4 

ldind.r8 

ldind.ref 

ldind.u1 

ldind.u2 

ldind.u4 

ldind.u8 

ldlen 

ldloc 

ldloc.0 

ldloc.1 

ldloc.2 

ldloc.3 

ldloc.s 

ldloca 

ldloca.s 

ldnull 

ldobj 

ldsfld 

ldsflda 

ldstr 

ldtoken 

ldvirtftn 

background image

419 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

leave 

leave.s 

linkcheck 

literal 

localloc 

lpstr 

lpstruct 

lptstr 

lpvoid 

lpwstr 

managed 

marshal 

method 

mkrefany 

modopt 

modreq 

mul 

mul.ovf 

mul.ovf.un 

native 

neg 

nested 

newarr 

newobj 

newslot 

noappdomain 

noinlining 

nomachine 

nomangle 

nometadata 

noncasdemand 

noncasinheritance 

noncaslinkdemand 

nop 

noprocess 

not 

not̲in̲gc̲heap 

notremotable 

notserialized 

null 

nullref 

object 

objectref 

opt 

optil 

or 

out 

permitonly 

pinned 

pinvokeimpl 

pop 

prefix1 

prefix2 

prefix3 

prefix4 

prefix5 

prefix6 

prefix7 

prefixref 

prejitdeny 

prejitgrant 

preservesig 

private 

privatescope 

protected 

public 

readonly 

record 

refany 

refanytype 

refanyval 

rem 

rem.un 

reqmin 

reqopt 

reqrefuse 

reqsecobj 

request 

ret 

rethrow 

retval 

rtspecialname 

runtime 

safearray 

sealed 

sequential 

serializable 

shl 

shr 

shr.un 

sizeof 

special 

specialname 

starg 

starg.s 

static 

stdcall 

stdcall 

stelem.i 

stelem.i1 

stelem.i2 

stelem.i4 

stelem.i8 

stelem.r4 

stelem.r8 

stelem.ref 

stfld 

stind.i 

stind.i1 

stind.i2 

stind.i4 

stind.i8 

stind.r4 

stind.r8 

stind.ref 

stloc 

stloc.0 

stloc.1 

stloc.2 

stloc.3 

stloc.s 

stobj 

storage 

stored̲object 

stream 

streamed̲object 

string 

struct 

stsfld 

sub 

sub.ovf 

sub.ovf.un 

switch 

synchronized 

syschar 

sysstring 

tail. 

tbstr 

thiscall 

thiscall 

throw 

tls 

to 

true 

typedref 

unaligned. 

unbox 

unicode 

unmanaged 

unmanagedexp 

unsigned 

unused 

userdefined 

value 

valuetype 

vararg 

variant 

vector 

virtual 

void 

volatile. 

wchar 

winapi 

with 

wrapper 

xor 

420 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

C.2 CILオプコードに関する説明 

この細分箇条では,C又はC++プリプロセッサでの利用が想定されるテキストについて説明する。マク

ロOPDEF及びOPALIASを適切に定義した後にこのテキストを含めることによって,このテキストを利用

して,CIL命令を処理するためのテーブル又はコードを作成することが可能になる。 

OPDEFマクロには,次の順序で10個の実引数が渡される。 

1) CEE̲で始まる,オプコードのシンボル名。 

2) オプコードの名前を構成し,第3章で指定した名前に対応する文字列。 

3) この演算結果を処理するためにスタックから削除されるデータ。利用可能な値は次のとおりとする。 

a) Pop0 − 入力値なし。 

b) Pop1 − データフローによって指定される一つの値型。 

c) Pop1+Pop1 − 二つの入力値,型はデータフローによって指定。 

d) PopI − マシンサイズの一つの整数。 

e) PopI+Pop1 − スタックのトップがデータフローによって説明されており,次の項目がプラッ

トフォーム固有ポインタである。 

f) 

PopI+PopI − スタックのトップ二つの項目が整数(サイズは,命令によって異なる場合があ

る。)。 

g) PopI+PopI+PopI − スタックのトップ三つの項目が,マシンサイズの整数。 

h) PopI8+Pop8 − スタックのトップは8バイトの整数。次は,プラットフォーム固有ポインタ。 

i) 

PopI+PopR4 − スタックのトップは4バイトの浮動小数点数。次は,プラットフォーム固有

ポインタ。 

j) 

PopI+PopR8 − スタックのトップは8バイトの浮動小数点数。次は,プラットフォーム固有

ポインタ。 

k) PopRef − スタックのトップはオブジェクト参照。 

l) 

PopRef+PopI − スタックのトップは整数(サイズは,命令によって異なる場合がある。)。次

は,オブジェクト参照。 

m) PopRef+PopI+PopI − スタックのトップは二つの整数(サイズは,命令によって異なる場合

がある。)。次は,オブジェクト参照。 

n) PopRef+PopI+PopI8 − スタックのトップは8バイト整数。次は,プラットフォーム固有サイ

ズの整数。その次は,オブジェクト参照。 

o) PopRef+PopI+PopR4 − スタックのトップは4バイト浮動小数点数。次は,プラットフォー

ム固有サイズの整数。その次は,オブジェクト参照。 

p) PopRef+PopI+PopR8 − スタックのトップは8バイト浮動小数点数。次は,プラットフォー

ム固有サイズの整数。その次は,オブジェクト参照。 

q) VarPop − 利用される可変個数の項目。詳細については,第3章を参照する。 

4) 命令の結果としてプッシュされるデータの量及び型。利用可能な値は次のとおりとする。 

a) Push0 − 出力値なし。 

b) Push1 − 一つの出力値,型はデータフローによって指定。 

c) Push1+Push1 − 二つの出力値,型はデータフローによって指定。 

d) PushI − 一つのネイティブ整数又はプラットフォーム固有ポインタをプッシュ。 

e) PushI8 − 一つの8バイト整数をプッシュ。 

421 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

f) 

PushR4 − 一つの4バイト浮動小数点数をプッシュ。 

g) PushR8 − 一つの8バイト浮動小数点数をプッシュ。 

h) PushRef − 一つのオブジェクト参照をプッシュ。 

i) 

VarPush − プッシュされる可変個数の項目。詳細については,第3章を参照する。 

5) 命令に対するインライン実引数の型。インライン実引数は,最下位バイトから先に格納される(“リ

トルエンディアン”)。利用可能な値は次のとおりとする。 

a) InlineBrTarget − 現在の命令に続く命令の最初から4バイト符号付き整数によって表される

分岐の対象。 

b) InlineField − FieldRef(フィールドに対するMemberRef)又はFieldDefを表すメタデータト

ークン(4バイト)。 

c) InlineI − 4バイト整数。 

d) InlineI8 − 8バイト整数。 

e) InlineMethod − MethodRef(メソッドに対するMemberRef。)又はMethodDefを表すメタデ

ータトークン(4バイト)。 

f) 

InlineNone − インライン実引数なし。 

g) InlineR − 8バイト浮動小数点数。 

h) InlineSig − スタンドアロン識別情報を表すメタデータトークン(4バイト)。 

i) 

InlineString − UserStringを表すメタデータトークン(4 バイト)。 

j) 

InlineSwitch − switch命令に対してだけ利用(第3章参照)。 

k) InlineTok − ldtoken命令に利用される任意のメタデータトークン(4バイト)(第3章参照)。 

l) 

InlineType − TypeDef,TypeRef,又はTypeSpecを表すメタデータトークン(4バイト)。 

m) InlineVar − 実引数又は局所変数を表す2バイト整数。 

n) ShortInlineBrTarget − 現在の命令に続く命令の最初から符号付き1バイトとして表される短

い分岐の対象。 

o) ShortInlineI − 命令に応じて1バイト整数,符号付き,又は符号なし。 

p) ShortInlineR − 4バイト浮動小数点数。 

q) ShortInlineVar − 実引数又は局所変数を表す1バイト整数。 

6) オプコードの種類。現在の分類は現在の値を含まないが,過去との互換性のために残される。 

7) オプコードのバイト数。現時点では1又は2,将来的には4が利用可能。 

8) 2バイト符号化の最初のバイト,又はシングルバイト命令である場合は0xFF。 

9) 1バイト符号化,又は2バイト符号化の2番目のバイト。 

10) 命令の制御フローの指定。利用可能な値は次のとおりとする。 

a) BRANCH − 無条件分岐。 

b) CALL − メソッド呼出し。 

c) COND̲BRANCH − 条件分岐。 

d) META − 未使用の演算又は前置コード。 

e) NEXT − 制御フローに変更なし(“フォールスルー”)。 

f) 

RETURN − メソッドから戻る。 

g) THROW − 例外の送出又は再送出。 

OPALIASマクロは,次の三つの実引数をとる。 

background image

422 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

1) “新しい命令”のシンボル名。既存の命令の別名(アセンブラのための名前変更)にすぎない。 

2) “新しい命令”の文字列名。 

3) OPDEFマクロを用いて導入された命令のシンボル名。“新しい命令”は,この命令の代替名にすぎ

ない。 

#ifndef ̲̲OPCODE̲DEF̲ 

#define ̲̲OPCODE̲DEF̲ 

#define MOOT    0x00    // Marks unused second byte when encoding single 

#define STP1    0xFE    // Prefix code 1 for Standard Map 

#define REFPRE  0xFF    // Prefix for Reference Code Encoding 

#define RESERVED̲PREFIX̲START 0xF7 

#endif 

// If the first byte of the standard encoding is 0xFF, then 

// the second byte can be used as 1 byte encoding.  Otherwise                

l   b         b 

// the encoding is two bytes.                                                                                               

e   y         y 

//                                                                              

n   t         t 

//                                                                              

g   e         e 

//                                                                              

(unused)       t 

//  Canonical Name                    String Name              Stack 

Behaviour           Operand Params    Opcode Kind      h   1         2   

Control Flow 

// 

------------------------------------------------------------------

------------------------------------------------------------------

------------------- 

OPDEF(CEE̲NOP,                        "nop",              Pop0,            

Push0,       InlineNone,         IPrimitive,  1,  0xFF,    0x00,    

NEXT) 

OPDEF(CEE̲BREAK,                      "break",            Pop0,           

Push0,       InlineNone,         IPrimitive,  1,  0xFF,    0x01,    

BREAK) 

OPDEF(CEE̲LDARG̲0,                    "ldarg.0",          Pop0,               

423 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

Push1,       InlineNone,         IMacro,      1,  0xFF,    0x02,    

NEXT) 

OPDEF(CEE̲LDARG̲1,                    "ldarg.1",          Pop0,           

Push1,       InlineNone,         IMacro,      1,  0xFF,    0x03,    

NEXT) 

OPDEF(CEE̲LDARG̲2,                    "ldarg.2",          Pop0,           

Push1,       InlineNone,         IMacro,      1,  0xFF,    0x04,    

NEXT) 

OPDEF(CEE̲LDARG̲3,                    "ldarg.3",          Pop0,          

h1,       InlineNone,         IMacro,      1,  0xFF,    0x05,    NEXT) 

OPDEF(CEE̲LDLOC̲0,                    "ldloc.0",          Pop0,           

Push1,       InlineNone,         IMacro,      1,  0xFF,    0x06,    

NEXT) 

OPDEF(CEE̲LDLOC̲1,                    "ldloc.1",          Pop0,           

Push1,       InlineNone,         IMacro,      1,  0xFF,    0x07,    

NEXT) 

OPDEF(CEE̲LDLOC̲2,                    "ldloc.2",          Pop0,           

Push1,       InlineNone,         IMacro,      1,  0xFF,    0x08,    

NEXT) 

OPDEF(CEE̲LDLOC̲3,                    "ldloc.3",          Pop0,           

Push1,       InlineNone,         IMacro,      1,  0xFF,    0x09,    

NEXT) 

OPDEF(CEE̲STLOC̲0,                    "stloc.0",          Pop1,           

Push0,       InlineNone,         IMacro,      1,  0xFF,    0x0A,    

NEXT) 

OPDEF(CEE̲STLOC̲1,                    "stloc.1",          Pop1,           

Push0,       InlineNone,         IMacro,      1,  0xFF,    0x0B,    

NEXT) 

OPDEF(CEE̲STLOC̲2,                    "stloc.2",          Pop1,           

Push0,       InlineNone,         IMacro,      1,  0xFF,    0x0C,    

NEXT) 

OPDEF(CEE̲STLOC̲3,                    "stloc.3",          Pop1,           

Push0,       InlineNone,         IMacro,      1,  0xFF,    0x0D,    

NEXT) 

OPDEF(CEE̲LDARG̲S,                    "ldarg.s",          Pop0,           

Push1,       ShortInlineVar,     IMacro,      1,  0xFF,    0x0E,    

NEXT) 

OPDEF(CEE̲LDARGA̲S,                   "ldarga.s",         Pop0,          

PushI,       ShortInlineVar,     IMacro,      1,  0xFF,    0x0F,    

NEXT) 

424 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

OPDEF(CEE̲STARG̲S,                    "starg.s",          Pop1,           

Push0,       ShortInlineVar,     IMacro,      1,  0xFF,    0x10,    

NEXT) 

OPDEF(CEE̲LDLOC̲S,                    "ldloc.s",          Pop0,           

Push1,       ShortInlineVar,     IMacro,      1,  0xFF,    0x11,    

NEXT) 

OPDEF(CEE̲LDLOCA̲S,                   "ldloca.s",         Pop0,          

PushI,       ShortInlineVar,     IMacro,      1,  0xFF,    0x12,    

NEXT) 

OPDEF(CEE̲STLOC̲S,                    "stloc.s",          Pop1,           

Push0,       ShortInlineVar,     IMacro,      1,  0xFF,    0x13,    

NEXT) 

OPDEF(CEE̲LDNULL,                     "ldnull",           Pop0,           

PushRef,     InlineNone,         IPrimitive,  1,  0xFF,    0x14,    

NEXT) 

OPDEF(CEE̲LDC̲I4̲M1,                  "ldc.i4.m1",        Pop0,          

PushI,       InlineNone,         IMacro,      1,  0xFF,    0x15,    

NEXT) 

OPDEF(CEE̲LDC̲I4̲0,                   "ldc.i4.0",         Pop0,          

PushI,       InlineNone,         IMacro,      1,  0xFF,    0x16,    

NEXT) 

OPDEF(CEE̲LDC̲I4̲1,                   "ldc.i4.1",         Pop0,          

PushI,       InlineNone,         IMacro,      1,  0xFF,    0x17,    

NEXT) 

OPDEF(CEE̲LDC̲I4̲2,                   "ldc.i4.2",         Pop0,               

PushI,       InlineNone,         IMacro,      1,  0xFF,    0x18,    

NEXT) 

OPDEF(CEE̲LDC̲I4̲3,                   "ldc.i4.3",         Pop0,               

PushI,       InlineNone,         IMacro,      1,  0xFF,    0x19,    

NEXT) 

OPDEF(CEE̲LDC̲I4̲4,                   "ldc.i4.4",         Pop0,               

PushI,       InlineNone,         IMacro,      1,  0xFF,    0x1A,    

NEXT) 

OPDEF(CEE̲LDC̲I4̲5,                   "ldc.i4.5",         Pop0,               

PushI,       InlineNone,         IMacro,      1,  0xFF,    0x1B,    

NEXT) 

OPDEF(CEE̲LDC̲I4̲6,                   "ldc.i4.6",         Pop0,               

PushI,       InlineNone,         IMacro,      1,  0xFF,    0x1C,    

NEXT) 

OPDEF(CEE̲LDC̲I4̲7,                   "ldc.i4.7",         Pop0,               

425 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

PushI,       InlineNone,         IMacro,      1,  0xFF,    0x1D,    

NEXT) 

OPDEF(CEE̲LDC̲I4̲8,                   "ldc.i4.8",         Pop0,          

PushI,       InlineNone,         IMacro,      1,  0xFF,    0x1E,    

NEXT) 

OPDEF(CEE̲LDC̲I4̲S,                   "ldc.i4.s",         Pop0,          

PushI,       ShortInlineI,       IMacro,      1,  0xFF,    0x1F,    

NEXT) 

OPDEF(CEE̲LDC̲I4,                     "ldc.i4",           Pop0,           

PushI,       InlineI,            IPrimitive,  1,  0xFF,    0x20,    

NEXT) 

OPDEF(CEE̲LDC̲I8,                     "ldc.i8",           Pop0,           

PushI8,      InlineI8,           IPrimitive,  1,  0xFF,    0x21,    

NEXT) 

OPDEF(CEE̲LDC̲R4,                     "ldc.r4",           Pop0,           

PushR4,      ShortInlineR,       IPrimitive,  1,  0xFF,    0x22,    

NEXT) 

OPDEF(CEE̲LDC̲R8,                     "ldc.r8",           Pop0,           

PushR8,      InlineR,            IPrimitive,  1,  0xFF,    0x23,    

NEXT) 

OPDEF(CEE̲UNUSED49,                   "unused",  

  Pop0, 

Push0,       InlineNone,         IPrimitive,  1,  0xFF,    0x24,    

NEXT) 

OPDEF(CEE̲DUP,                        "dup",              Pop1,            

Push1+Push1, InlineNone,         IPrimitive,  1,  0xFF,    0x25,    

NEXT) 

OPDEF(CEE̲POP,                        "pop",              Pop1,            

Push0,       InlineNone,         IPrimitive,  1,  0xFF,    0x26,    

NEXT) 

OPDEF(CEE̲JMP,                        "jmp",              Pop0,            

Push0,       InlineMethod,       IPrimitive,  1,  0xFF,    0x27,    

CALL) 

OPDEF(CEE̲CALL,                       "call",             VarPop,         

VarPush,     InlineMethod,       IPrimitive,  1,  0xFF,    0x28,    

CALL) 

OPDEF(CEE̲CALLI,                      "calli",            VarPop,         

VarPush,     InlineSig,          IPrimitive,  1,  0xFF,    0x29,    

CALL) 

OPDEF(CEE̲RET,                        "ret",              VarPop,          

Push0,       InlineNone,         IPrimitive,  1,  0xFF,    0x2A,    

426 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

RETURN) 

OPDEF(CEE̲BR̲S,                       "br.s",             Pop0,            

Push0,       ShortInlineBrTarget,IMacro,      1,  0xFF,    0x2B,    

BRANCH) 

OPDEF(CEE̲BRFALSE̲S,                  "brfalse.s",        PopI,          

Push0,       ShortInlineBrTarget,IMacro,      1,  0xFF,    0x2C,    

COND̲BRANCH) 

OPDEF(CEE̲BRTRUE̲S,                   "brtrue.s",         PopI,          

Push0,       ShortInlineBrTarget,IMacro,      1,  0xFF,    0x2D,    

COND̲BRANCH) 

OPDEF(CEE̲BEQ̲S,                      "beq.s",            Pop1+Pop1,     

Push0,       ShortInlineBrTarget,IMacro,      1,  0xFF,    0x2E,    

COND̲BRANCH) 

OPDEF(CEE̲BGE̲S,                      "bge.s",            Pop1+Pop1,     

Push0,       ShortInlineBrTarget,IMacro,      1,  0xFF,    0x2F,    

COND̲BRANCH) 

OPDEF(CEE̲BGT̲S,                      "bgt.s",            Pop1+Pop1,     

Push0,       ShortInlineBrTarget,IMacro,      1,  0xFF,    0x30,    

COND̲BRANCH) 

OPDEF(CEE̲BLE̲S,                      "ble.s",            Pop1+Pop1,     

Push0,       ShortInlineBrTarget,IMacro,      1,  0xFF,    0x31,    

COND̲BRANCH) 

OPDEF(CEE̲BLT̲S,                      "blt.s",            Pop1+Pop1,     

Push0,       ShortInlineBrTarget,IMacro,      1,  0xFF,    0x32,    

COND̲BRANCH) 

OPDEF(CEE̲BNE̲UN̲S,                   "bne.un.s",         Pop1+Pop1,    

Push0,       ShortInlineBrTarget,IMacro,      1,  0xFF,    0x33,    

COND̲BRANCH) 

OPDEF(CEE̲BGE̲UN̲S,                   "bge.un.s",         Pop1+Pop1,    

Push0,       ShortInlineBrTarget,IMacro,      1,  0xFF,    0x34,    

COND̲BRANCH) 

OPDEF(CEE̲BGT̲UN̲S,                   "bgt.un.s",         Pop1+Pop1,    

Push0,       ShortInlineBrTarget,IMacro,      1,  0xFF,    0x35,    

COND̲BRANCH) 

OPDEF(CEE̲BLE̲UN̲S,                   "ble.un.s",         Pop1+Pop1,    

Push0,       ShortInlineBrTarget,IMacro,      1,  0xFF,    0x36,    

COND̲BRANCH) 

OPDEF(CEE̲BLT̲UN̲S,                   "blt.un.s",         Pop1+Pop1,    

Push0,       ShortInlineBrTarget,IMacro,      1,  0xFF,    0x37,    

COND̲BRANCH) 

427 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

OPDEF(CEE̲BR,                         "br",               Pop0,             

Push0,       InlineBrTarget,     IPrimitive,  1,  0xFF,    0x38,    

BRANCH) 

OPDEF(CEE̲BRFALSE,                    "brfalse",          PopI,           

Push0,       InlineBrTarget,     IPrimitive,  1,  0xFF,    0x39,    

COND̲BRANCH) 

OPDEF(CEE̲BRTRUE,                     "brtrue",           PopI,           

Push0,       InlineBrTarget,     IPrimitive,  1,  0xFF,    0x3A,    

COND̲BRANCH) 

OPDEF(CEE̲BEQ,                        "beq",              Pop1+Pop1,      

Push0,       InlineBrTarget,     IMacro,      1,  0xFF,    0x3B,    

COND̲BRANCH) 

OPDEF(CEE̲BGE,                        "bge",              Pop1+Pop1,      

Push0,       InlineBrTarget,     IMacro,      1,  0xFF,    0x3C,    

COND̲BRANCH) 

OPDEF(CEE̲BGT,                        "bgt",              Pop1+Pop1,      

Push0,       InlineBrTarget,     IMacro,      1,  0xFF,    0x3D,    

COND̲BRANCH) 

OPDEF(CEE̲BLE,                        "ble",              Pop1+Pop1,      

Push0,       InlineBrTarget,     IMacro,      1,  0xFF,    0x3E,    

COND̲BRANCH) 

OPDEF(CEE̲BLT,                        "blt",              Pop1+Pop1,      

Push0,       InlineBrTarget,     IMacro,      1,  0xFF,    0x3F,    

COND̲BRANCH) 

OPDEF(CEE̲BNE̲UN,                     "bne.un",           Pop1+Pop1,     

Push0,       InlineBrTarget,     IMacro,      1,  0xFF,    0x40,    

COND̲BRANCH) 

OPDEF(CEE̲BGE̲UN,                     "bge.un",           Pop1+Pop1,     

Push0,       InlineBrTarget,     IMacro,      1,  0xFF,    0x41,    

COND̲BRANCH) 

OPDEF(CEE̲BGT̲UN,                     "bgt.un",           Pop1+Pop1,     

Push0,       InlineBrTarget,     IMacro,      1,  0xFF,    0x42,    

COND̲BRANCH) 

OPDEF(CEE̲BLE̲UN,                     "ble.un",           Pop1+Pop1,     

Push0,       InlineBrTarget,     IMacro,      1,  0xFF,    0x43,    

COND̲BRANCH) 

OPDEF(CEE̲BLT̲UN,                     "blt.un",           Pop1+Pop1,     

Push0,       InlineBrTarget,     IMacro,      1,  0xFF,    0x44,    

COND̲BRANCH) 

OPDEF(CEE̲SWITCH,                     "switch",           PopI,           

428 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

Push0,       InlineSwitch,       IPrimitive,  1,  0xFF,    0x45,    

COND̲BRANCH) 

OPDEF(CEE̲LDIND̲I1,                   "ldind.i1",         PopI,          

PushI,       InlineNone,         IPrimitive,  1,  0xFF,    0x46,    

NEXT) 

OPDEF(CEE̲LDIND̲U1,                   "ldind.u1",         PopI,          

PushI,       InlineNone,         IPrimitive,  1,  0xFF,    0x47,    

NEXT) 

OPDEF(CEE̲LDIND̲I2,                   "ldind.i2",         PopI,          

PushI,       InlineNone,         IPrimitive,  1,  0xFF,    0x48,    

NEXT) 

OPDEF(CEE̲LDIND̲U2,                   "ldind.u2",         PopI,          

PushI,       InlineNone,         IPrimitive,  1,  0xFF,    0x49,    

NEXT) 

OPDEF(CEE̲LDIND̲I4,                   "ldind.i4",         PopI,          

PushI,       InlineNone,         IPrimitive,  1,  0xFF,    0x4A,    

NEXT) 

OPDEF(CEE̲LDIND̲U4,                   "ldind.u4",         PopI,          

PushI,       InlineNone,         IPrimitive,  1,  0xFF,    0x4B,    

NEXT) 

OPDEF(CEE̲LDIND̲I8,                   "ldind.i8",         PopI,          

PushI8,      InlineNone,         IPrimitive,  1,  0xFF,    0x4C,    

NEXT) 

OPDEF(CEE̲LDIND̲I,                    "ldind.i",          PopI,          

PushI,       InlineNone,         IPrimitive,  1,  0xFF,    0x4D,    

NEXT) 

OPDEF(CEE̲LDIND̲R4,                   "ldind.r4",         PopI,          

PushR4,      InlineNone,         IPrimitive,  1,  0xFF,    0x4E,    

NEXT) 

OPDEF(CEE̲LDIND̲R8,                   "ldind.r8",         PopI,          

PushR8,      InlineNone,         IPrimitive,  1,  0xFF,    0x4F,    

NEXT) 

OPDEF(CEE̲LDIND̲REF,                  "ldind.ref",        PopI,          

PushRef,     InlineNone,         IPrimitive,  1,  0xFF,    0x50,    

NEXT) 

OPDEF(CEE̲STIND̲REF,                  "stind.ref",        PopI+PopI,    

Push0,       InlineNone,         IPrimitive,  1,  0xFF,    0x51,    

NEXT) 

OPDEF(CEE̲STIND̲I1,                   "stind.i1",         PopI+PopI,    

Push0,       InlineNone,         IPrimitive,  1,  0xFF,    0x52,    

429 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

NEXT) 

OPDEF(CEE̲STIND̲I2,                   "stind.i2",         PopI+PopI,    

Push0,       InlineNone,         IPrimitive,  1,  0xFF,    0x53,    

NEXT) 

OPDEF(CEE̲STIND̲I4,                   "stind.i4",         PopI+PopI,    

Push0,       InlineNone,         IPrimitive,  1,  0xFF,    0x54,    

NEXT) 

OPDEF(CEE̲STIND̲I8,                   "stind.i8",         PopI+PopI8,   

Push0,       InlineNone,         IPrimitive,  1,  0xFF,    0x55,    

NEXT) 

OPDEF(CEE̲STIND̲R4,                   "stind.r4",         PopI+PopR4,   

Push0,       InlineNone,         IPrimitive,  1,  0xFF,    0x56,    

NEXT) 

OPDEF(CEE̲STIND̲R8,                   "stind.r8",         PopI+PopR8,   

Push0,       InlineNone,         IPrimitive,  1,  0xFF,    0x57,    

NEXT) 

OPDEF(CEE̲ADD,                        "add",              Pop1+Pop1,      

Push1,       InlineNone,         IPrimitive,  1,  0xFF,    0x58,    

NEXT) 

OPDEF(CEE̲SUB,                        "sub",              Pop1+Pop1,      

Push1,       InlineNone,         IPrimitive,  1,  0xFF,    0x59,    

NEXT) 

OPDEF(CEE̲MUL,                        "mul",              Pop1+Pop1,      

Push1,       InlineNone,         IPrimitive,  1,  0xFF,    0x5A,    

NEXT) 

OPDEF(CEE̲DIV,                        "div",              Pop1+Pop1,      

Push1,       InlineNone,         IPrimitive,  1,  0xFF,    0x5B,    

NEXT) 

OPDEF(CEE̲DIV̲UN,                     "div.un",           Pop1+Pop1,     

Push1,       InlineNone,         IPrimitive,  1,  0xFF,    0x5C,    

NEXT) 

OPDEF(CEE̲REM,                        "rem",              Pop1+Pop1,      

Push1,       InlineNone,         IPrimitive,  1,  0xFF,    0x5D,    

NEXT) 

OPDEF(CEE̲REM̲UN,                     "rem.un",           Pop1+Pop1,     

Push1,       InlineNone,         IPrimitive,  1,  0xFF,    0x5E,    

NEXT) 

OPDEF(CEE̲AND,                        "and",              Pop1+Pop1,      

Push1,       InlineNone,         IPrimitive,  1,  0xFF,    0x5F,    

NEXT) 

430 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

OPDEF(CEE̲OR,                         "or",               Pop1+Pop1,       

Push1,       InlineNone,         IPrimitive,  1,  0xFF,    0x60,    

NEXT) 

OPDEF(CEE̲XOR,                        "xor",              Pop1+Pop1,      

Push1,       InlineNone,         IPrimitive,  1,  0xFF,    0x61,    

NEXT) 

OPDEF(CEE̲SHL,                        "shl",              Pop1+Pop1,      

Push1,       InlineNone,         IPrimitive,  1,  0xFF,    0x62,    

NEXT) 

OPDEF(CEE̲SHR,                        "shr",              Pop1+Pop1,      

Push1,       InlineNone,         IPrimitive,  1,  0xFF,    0x63,    

NEXT) 

OPDEF(CEE̲SHR̲UN,                     "shr.un",           Pop1+Pop1,     

Push1,       InlineNone,         IPrimitive,  1,  0xFF,    0x64,    

NEXT) 

OPDEF(CEE̲NEG,                        "neg",              Pop1,            

Push1,       InlineNone,         IPrimitive,  1,  0xFF,    0x65,    

NEXT) 

OPDEF(CEE̲NOT,                        "not",              Pop1,            

Push1,       InlineNone,         IPrimitive,  1,  0xFF,    0x66,    

NEXT) 

OPDEF(CEE̲CONV̲I1,                    "conv.i1",          Pop1,           

PushI,       InlineNone,         IPrimitive,  1,  0xFF,    0x67,    

NEXT) 

OPDEF(CEE̲CONV̲I2,                    "conv.i2",          Pop1,           

PushI,       InlineNone,         IPrimitive,  1,  0xFF,    0x68,    

NEXT) 

OPDEF(CEE̲CONV̲I4,                    "conv.i4",          Pop1,           

PushI,       InlineNone,         IPrimitive,  1,  0xFF,    0x69,    

NEXT) 

OPDEF(CEE̲CONV̲I8,                    "conv.i8",          Pop1,           

PushI8,      InlineNone,         IPrimitive,  1,  0xFF,    0x6A,    

NEXT) 

OPDEF(CEE̲CONV̲R4,                    "conv.r4",          Pop1,           

PushR4,      InlineNone,         IPrimitive,  1,  0xFF,    0x6B,    

NEXT) 

OPDEF(CEE̲CONV̲R8,                    "conv.r8",          Pop1,           

PushR8,      InlineNone,         IPrimitive,  1,  0xFF,    0x6C,    

NEXT) 

OPDEF(CEE̲CONV̲U4,                    "conv.u4",          Pop1,           

431 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

PushI,       InlineNone,         IPrimitive,  1,  0xFF,    0x6D,    

NEXT) 

OPDEF(CEE̲CONV̲U8,                    "conv.u8",          Pop1,          

PushI8,      InlineNone,         IPrimitive,  1,  0xFF,    0x6E,    

NEXT) 

OPDEF(CEE̲CALLVIRT,                   "callvirt",         VarPop,       

VarPush,     InlineMethod,       IObjModel,   1,  0xFF,    0x6F,    

CALL) 

OPDEF(CEE̲CPOBJ,                      "cpobj",            PopI+PopI,     

Push0,       InlineType,         IObjModel,   1,  0xFF,    0x70,    

NEXT) 

OPDEF(CEE̲LDOBJ,                      "ldobj",            PopI,           

Push1,       InlineType,         IObjModel,   1,  0xFF,    0x71,    

NEXT) 

OPDEF(CEE̲LDSTR,                      "ldstr",            Pop0,           

PushRef,     InlineString,       IObjModel,   1,  0xFF,    0x72,    

NEXT) 

OPDEF(CEE̲NEWOBJ,                     "newobj",           VarPop,         

PushRef,     InlineMethod,       IObjModel,   1,  0xFF,    0x73,    

CALL) 

OPDEF(CEE̲CASTCLASS,                  "castclass",        PopRef,       

PushRef,     InlineType,         IObjModel,   1,  0xFF,    0x74,    

NEXT) 

OPDEF(CEE̲ISINST,                     "isinst",           PopRef,         

PushI,       InlineType,         IObjModel,   1,  0xFF,    0x75,    

NEXT) 

OPDEF(CEE̲CONV̲R̲UN,                  "conv.r.un",        Pop1,          

PushR8,      InlineNone,         IPrimitive,  1,  0xFF,    0x76,    

NEXT) 

OPDEF(CEE̲UNUSED58,                   "unused",           Pop0,           

Push0,       InlineNone,         IPrimitive,  1,  0xFF,    0x77,    

NEXT) 

OPDEF(CEE̲UNUSED1,                    "unused",           Pop0,           

Push0,       InlineNone,         IPrimitive,  1,  0xFF,    0x78,    

NEXT) 

OPDEF(CEE̲UNBOX,                      "unbox",            PopRef,         

PushI,       InlineType,         IPrimitive,  1,  0xFF,    0x79,    

NEXT) 

OPDEF(CEE̲THROW,                      "throw",            PopRef,         

Push0,       InlineNone,         IObjModel,   1,  0xFF,    0x7A,    

432 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

THROW) 

OPDEF(CEE̲LDFLD,                      "ldfld",            PopRef,         

Push1,       InlineField,        IObjModel,   1,  0xFF,    0x7B,    

NEXT) 

OPDEF(CEE̲LDFLDA,                     "ldflda",           PopRef,         

PushI,       InlineField,        IObjModel,   1,  0xFF,    0x7C,    

NEXT) 

OPDEF(CEE̲STFLD,                      "stfld",            PopRef+Pop1,   

Push0,       InlineField,        IObjModel,   1,  0xFF,    0x7D,    

NEXT) 

OPDEF(CEE̲LDSFLD,                     "ldsfld",           Pop0,           

Push1,       InlineField,        IObjModel,   1,  0xFF,    0x7E,    

NEXT) 

OPDEF(CEE̲LDSFLDA,                    "ldsflda",          Pop0,           

PushI,       InlineField,        IObjModel,   1,  0xFF,    0x7F,    

NEXT) 

OPDEF(CEE̲STSFLD,                     "stsfld",           Pop1,           

Push0,       InlineField,        IObjModel,   1,  0xFF,    0x80,    

NEXT) 

OPDEF(CEE̲STOBJ,                      "stobj",            PopI+Pop1,      

Push0,       InlineType,         IPrimitive,  1,  0xFF,    0x81,    

NEXT) 

OPDEF(CEE̲CONV̲OVF̲I1̲UN,             "conv.ovf.i1.un",   Pop1,        

PushI,       InlineNone,         IPrimitive,  1,  0xFF,    0x82,    

NEXT) 

OPDEF(CEE̲CONV̲OVF̲I2̲UN,             "conv.ovf.i2.un",   Pop1,        

PushI,       InlineNone,         IPrimitive,  1,  0xFF,    0x83,    

NEXT) 

OPDEF(CEE̲CONV̲OVF̲I4̲UN,             "conv.ovf.i4.un",   Pop1,        

PushI,       InlineNone,         IPrimitive,  1,  0xFF,    0x84,    

NEXT) 

OPDEF(CEE̲CONV̲OVF̲I8̲UN,             "conv.ovf.i8.un",   Pop1,        

PushI8,      InlineNone,         IPrimitive,  1,  0xFF,    0x85,    

NEXT) 

OPDEF(CEE̲CONV̲OVF̲U1̲UN,             "conv.ovf.u1.un",   Pop1,        

PushI,       InlineNone,         IPrimitive,  1,  0xFF,    0x86,    

NEXT) 

OPDEF(CEE̲CONV̲OVF̲U2̲UN,             "conv.ovf.u2.un",   Pop1,        

PushI,       InlineNone,         IPrimitive,  1,  0xFF,    0x87,    

NEXT) 

433 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

OPDEF(CEE̲CONV̲OVF̲U4̲UN,             "conv.ovf.u4.un",   Pop1,        

PushI,       InlineNone,         IPrimitive,  1,  0xFF,    0x88,    

NEXT) 

OPDEF(CEE̲CONV̲OVF̲U8̲UN,             "conv.ovf.u8.un",   Pop1,        

PushI8,      InlineNone,         IPrimitive,  1,  0xFF,    0x89,    

NEXT) 

OPDEF(CEE̲CONV̲OVF̲I̲UN,              "conv.ovf.i.un",    Pop1,        

PushI,       InlineNone,         IPrimitive,  1,  0xFF,    0x8A,    

NEXT) 

OPDEF(CEE̲CONV̲OVF̲U̲UN,              "conv.ovf.u.un",    Pop1,        

PushI,       InlineNone,         IPrimitive,  1,  0xFF,    0x8B,    

NEXT) 

OPDEF(CEE̲BOX,                        "box",              Pop1,            

PushRef,     InlineType,         IPrimitive,  1,  0xFF,    0x8C,    

NEXT) 

OPDEF(CEE̲NEWARR,                     "newarr",           PopI,           

PushRef,     InlineType,         IObjModel,   1,  0xFF,    0x8D,    

NEXT) 

OPDEF(CEE̲LDLEN,                      "ldlen",            PopRef,         

PushI,       InlineNone,         IObjModel,   1,  0xFF,    0x8E,    

NEXT) 

OPDEF(CEE̲LDELEMA,                    "ldelema",          PopRef+PopI,  

PushI,       InlineType,         IObjModel,   1,  0xFF,    0x8F,    

NEXT) 

OPDEF(CEE̲LDELEM̲I1,                  "ldelem.i1",        PopRef+PopI, 

PushI,       InlineNone,         IObjModel,   1,  0xFF,    0x90,    

NEXT) 

OPDEF(CEE̲LDELEM̲U1,                  "ldelem.u1",        PopRef+PopI, 

PushI,       InlineNone,         IObjModel,   1,  0xFF,    0x91,    

NEXT) 

OPDEF(CEE̲LDELEM̲I2,                  "ldelem.i2",        PopRef+PopI, 

PushI,       InlineNone,         IObjModel,   1,  0xFF,    0x92,    

NEXT) 

OPDEF(CEE̲LDELEM̲U2,                  "ldelem.u2",        PopRef+PopI, 

PushI,       InlineNone,         IObjModel,   1,  0xFF,    0x93,    

NEXT) 

OPDEF(CEE̲LDELEM̲I4,                  "ldelem.i4",        PopRef+PopI, 

PushI,       InlineNone,         IObjModel,   1,  0xFF,    0x94,    

NEXT) 

OPDEF(CEE̲LDELEM̲U4,                  "ldelem.u4",        PopRef+PopI, 

434 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

PushI,       InlineNone,         IObjModel,   1,  0xFF,    0x95,    

NEXT) 

OPDEF(CEE̲LDELEM̲I8,                  "ldelem.i8",        PopRef+PopI, 

PushI8,      InlineNone,         IObjModel,   1,  0xFF,    0x96,    

NEXT) 

OPDEF(CEE̲LDELEM̲I,                   "ldelem.i",         PopRef+PopI,  

PushI,       InlineNone,         IObjModel,   1,  0xFF,    0x97,    

NEXT) 

OPDEF(CEE̲LDELEM̲R4,                  "ldelem.r4",        PopRef+PopI, 

PushR4,      InlineNone,         IObjModel,   1,  0xFF,    0x98,    

NEXT) 

OPDEF(CEE̲LDELEM̲R8,                  "ldelem.r8",        PopRef+PopI, 

PushR8,      InlineNone,         IObjModel,   1,  0xFF,    0x99,    

NEXT) 

OPDEF(CEE̲LDELEM̲REF,                 "ldelem.ref",       PopRef+PopI, 

PushRef,     InlineNone,         IObjModel,   1,  0xFF,    0x9A,    

NEXT) 

OPDEF(CEE̲STELEM̲I,                   "stelem.i",         

PopRef+PopI+PopI,   Push0,       InlineNone,         IObjModel,   1,  

0xFF,    0x9B,    NEXT) 

OPDEF(CEE̲STELEM̲I1,                  "stelem.i1",        

PopRef+PopI+PopI,   Push0,       InlineNone,         IObjModel,   1,  

0xFF,    0x9C,    NEXT) 

OPDEF(CEE̲STELEM̲I2,                  "stelem.i2",        

PopRef+PopI+PopI,   Push0,       InlineNone,         IObjModel,   1,  

0xFF,    0x9D,    NEXT) 

OPDEF(CEE̲STELEM̲I4,                  "stelem.i4",        

PopRef+PopI+PopI,   Push0,       InlineNone,         IObjModel,   1,  

0xFF,    0x9E,    NEXT) 

OPDEF(CEE̲STELEM̲I8,                  "stelem.i8",        

PopRef+PopI+PopI8,  Push0,       InlineNone,         IObjModel,   1,  

0xFF,    0x9F,    NEXT) 

OPDEF(CEE̲STELEM̲R4,                  "stelem.r4",        

PopRef+PopI+PopR4,  Push0,       InlineNone,         IObjModel,   1,  

0xFF,    0xA0,    NEXT) 

OPDEF(CEE̲STELEM̲R8,                  "stelem.r8",        

PopRef+PopI+PopR8,  Push0,       InlineNone,         IObjModel,   1,  

0xFF,    0xA1,    NEXT) 

OPDEF(CEE̲STELEM̲REF,                 "stelem.ref",       

PopRef+PopI+PopRef, Push0,       InlineNone,         IObjModel,   1,  

435 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

0xFF,    0xA2,    NEXT) 

OPDEF(CEE̲UNUSED2,                    "unused",           Pop0,           

Push0,       InlineNone,         IPrimitive,  1,  0xFF,    0xA3,    

NEXT) 

OPDEF(CEE̲UNUSED3,                    "unused",           Pop0,           

Push0,       InlineNone,         IPrimitive,  1,  0xFF,    0xA4,    

NEXT) 

OPDEF(CEE̲UNUSED4,                    "unused",           Pop0,           

Push0,       InlineNone,         IPrimitive,  1,  0xFF,    0xA5,    

NEXT) 

OPDEF(CEE̲UNUSED5,                    "unused",           Pop0,           

Push0,       InlineNone,         IPrimitive,  1,  0xFF,    0xA6,    

NEXT) 

OPDEF(CEE̲UNUSED6,                    "unused",           Pop0,           

Push0,       InlineNone,         IPrimitive,  1,  0xFF,    0xA7,    

NEXT) 

OPDEF(CEE̲UNUSED7,                    "unused",           Pop0,           

Push0,       InlineNone,         IPrimitive,  1,  0xFF,    0xA8,    

NEXT) 

OPDEF(CEE̲UNUSED8,                    "unused",           Pop0,           

Push0,       InlineNone,         IPrimitive,  1,  0xFF,    0xA9,    

NEXT) 

OPDEF(CEE̲UNUSED9,                    "unused",           Pop0,           

Push0,       InlineNone,         IPrimitive,  1,  0xFF,    0xAA,    

NEXT) 

OPDEF(CEE̲UNUSED10,                   "unused",           Pop0,           

Push0,       InlineNone,         IPrimitive,  1,  0xFF,    0xAB,    

NEXT) 

OPDEF(CEE̲UNUSED11,                   "unused",           Pop0,           

Push0,       InlineNone,         IPrimitive,  1,  0xFF,    0xAC,    

NEXT) 

OPDEF(CEE̲UNUSED12,                   "unused",           Pop0,           

Push0,       InlineNone,         IPrimitive,  1,  0xFF,    0xAD,    

NEXT) 

OPDEF(CEE̲UNUSED13,                   "unused",           Pop0,           

Push0,       InlineNone,         IPrimitive,  1,  0xFF,    0xAE,    

NEXT) 

OPDEF(CEE̲UNUSED14,                   "unused",           Pop0,           

Push0,       InlineNone,         IPrimitive,  1,  0xFF,    0xAF,    

NEXT) 

436 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

OPDEF(CEE̲UNUSED15,                   "unused",           Pop0,           

Push0,       InlineNone,         IPrimitive,  1,  0xFF,    0xB0,    

NEXT) 

OPDEF(CEE̲UNUSED16,                   "unused",           Pop0,           

Push0,       InlineNone,         IPrimitive,  1,  0xFF,    0xB1,    

NEXT) 

OPDEF(CEE̲UNUSED17,                   "unused",           Pop0,           

Push0,       InlineNone,         IPrimitive,  1,  0xFF,    0xB2,    

NEXT) 

OPDEF(CEE̲CONV̲OVF̲I1,                "conv.ovf.i1",      Pop1,         

PushI,       InlineNone,         IPrimitive,  1,  0xFF,    0xB3,    

NEXT) 

OPDEF(CEE̲CONV̲OVF̲U1,                "conv.ovf.u1",      Pop1,         

PushI,       InlineNone,         IPrimitive,  1,  0xFF,    0xB4,    

NEXT) 

OPDEF(CEE̲CONV̲OVF̲I2,                "conv.ovf.i2",      Pop1,         

PushI,       InlineNone,         IPrimitive,  1,  0xFF,    0xB5,    

NEXT) 

OPDEF(CEE̲CONV̲OVF̲U2,                "conv.ovf.u2",      Pop1,         

PushI,       InlineNone,         IPrimitive,  1,  0xFF,    0xB6,    

NEXT) 

OPDEF(CEE̲CONV̲OVF̲I4,                "conv.ovf.i4",      Pop1,         

PushI,       InlineNone,         IPrimitive,  1,  0xFF,    0xB7,    

NEXT) 

OPDEF(CEE̲CONV̲OVF̲U4,                "conv.ovf.u4",      Pop1,         

PushI,       InlineNone,         IPrimitive,  1,  0xFF,    0xB8,    

NEXT) 

OPDEF(CEE̲CONV̲OVF̲I8,                "conv.ovf.i8",      Pop1,         

PushI8,      InlineNone,         IPrimitive,  1,  0xFF,    0xB9,    

NEXT) 

OPDEF(CEE̲CONV̲OVF̲U8,                "conv.ovf.u8",      Pop1,         

PushI8,      InlineNone,         IPrimitive,  1,  0xFF,    0xBA,    

NEXT) 

OPDEF(CEE̲UNUSED50,                   "unused",           Pop0,           

Push0,       InlineNone,         IPrimitive,  1,  0xFF,    0xBB,    

NEXT) 

OPDEF(CEE̲UNUSED18,                   "unused",           Pop0,           

Push0,       InlineNone,         IPrimitive,  1,  0xFF,    0xBC,    

NEXT) 

OPDEF(CEE̲UNUSED19,                   "unused",           Pop0,           

437 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

Push0,       InlineNone,         IPrimitive,  1,  0xFF,    0xBD,    

NEXT) 

OPDEF(CEE̲UNUSED20,                   "unused",           Pop0,           

Push0,       InlineNone,         IPrimitive,  1,  0xFF,    0xBE,    

NEXT) 

OPDEF(CEE̲UNUSED21,                   "unused",           Pop0,           

Push0,       InlineNone,         IPrimitive,  1,  0xFF,    0xBF,    

NEXT) 

OPDEF(CEE̲UNUSED22,                   "unused",           Pop0,           

Push0,       InlineNone,         IPrimitive,  1,  0xFF,    0xC0,    

NEXT) 

OPDEF(CEE̲UNUSED23,                   "unused",           Pop0,           

Push0,       InlineNone,         IPrimitive,  1,  0xFF,    0xC1,    

NEXT) 

OPDEF(CEE̲REFANYVAL,                  "refanyval",        Pop1,          

PushI,       InlineType,         IPrimitive,  1,  0xFF,    0xC2,    

NEXT) 

OPDEF(CEE̲CKFINITE,                   "ckfinite",         Pop1,          

PushR8,      InlineNone,         IPrimitive,  1,  0xFF,    0xC3,    

NEXT) 

OPDEF(CEE̲UNUSED24,                   "unused",           Pop0,           

Push0,       InlineNone,         IPrimitive,  1,  0xFF,    0xC4,    

NEXT) 

OPDEF(CEE̲UNUSED25,                   "unused",           Pop0,           

Push0,       InlineNone,         IPrimitive,  1,  0xFF,    0xC5,    

NEXT) 

OPDEF(CEE̲MKREFANY,                   "mkrefany",         PopI,          

Push1,       InlineType,         IPrimitive,  1,  0xFF,    0xC6,    

NEXT) 

OPDEF(CEE̲UNUSED59,                   "unused",           Pop0,           

Push0,       InlineNone,         IPrimitive,  1,  0xFF,    0xC7,    

NEXT) 

OPDEF(CEE̲UNUSED60,                   "unused",           Pop0,           

Push0,       InlineNone,         IPrimitive,  1,  0xFF,    0xC8,    

NEXT) 

OPDEF(CEE̲UNUSED61,                   "unused",           Pop0,           

Push0,       InlineNone,         IPrimitive,  1,  0xFF,    0xC9,    

NEXT) 

OPDEF(CEE̲UNUSED62,                   "unused",           Pop0,           

Push0,       InlineNone,         IPrimitive,  1,  0xFF,    0xCA,    

438 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

NEXT) 

OPDEF(CEE̲UNUSED63,                   "unused",           Pop0,           

Push0,       InlineNone,         IPrimitive,  1,  0xFF,    0xCB,    

NEXT) 

OPDEF(CEE̲UNUSED64,                   "unused",           Pop0,           

Push0,       InlineNone,         IPrimitive,  1,  0xFF,    0xCC,    

NEXT) 

OPDEF(CEE̲UNUSED65,                   "unused",           Pop0,           

Push0,       InlineNone,         IPrimitive,  1,  0xFF,    0xCD,    

NEXT) 

OPDEF(CEE̲UNUSED66,                   "unused",           Pop0,           

Push0,       InlineNone,         IPrimitive,  1,  0xFF,    0xCE,    

NEXT) 

OPDEF(CEE̲UNUSED67,                   "unused",           Pop0,           

Push0,       InlineNone,         IPrimitive,  1,  0xFF,    0xCF,    

NEXT) 

OPDEF(CEE̲LDTOKEN,                    "ldtoken",          Pop0,           

PushI,       InlineTok,          IPrimitive,  1,  0xFF,    0xD0,    

NEXT) 

OPDEF(CEE̲CONV̲U2,                    "conv.u2",          Pop1,           

PushI,       InlineNone,         IPrimitive,  1,  0xFF,    0xD1,    

NEXT) 

OPDEF(CEE̲CONV̲U1,                    "conv.u1",          Pop1,           

PushI,       InlineNone,         IPrimitive,  1,  0xFF,    0xD2,    

NEXT) 

OPDEF(CEE̲CONV̲I,                     "conv.i",           Pop1,           

PushI,       InlineNone,         IPrimitive,  1,  0xFF,    0xD3,    

NEXT) 

OPDEF(CEE̲CONV̲OVF̲I,                 "conv.ovf.i",       Pop1,         

PushI,       InlineNone,         IPrimitive,  1,  0xFF,    0xD4,    

NEXT) 

OPDEF(CEE̲CONV̲OVF̲U,                 "conv.ovf.u",       Pop1,         

PushI,       InlineNone,         IPrimitive,  1,  0xFF,    0xD5,    

NEXT) 

OPDEF(CEE̲ADD̲OVF,                    "add.ovf",          Pop1+Pop1,     

Push1,       InlineNone,         IPrimitive,  1,  0xFF,    0xD6,    

NEXT) 

OPDEF(CEE̲ADD̲OVF̲UN,                 "add.ovf.un",       Pop1+Pop1,   

Push1,       InlineNone,         IPrimitive,  1,  0xFF,    0xD7,    

NEXT) 

439 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

OPDEF(CEE̲MUL̲OVF,                    "mul.ovf",          Pop1+Pop1,     

Push1,       InlineNone,         IPrimitive,  1,  0xFF,    0xD8,    

NEXT) 

OPDEF(CEE̲MUL̲OVF̲UN,                 "mul.ovf.un",       Pop1+Pop1,   

Push1,       InlineNone,         IPrimitive,  1,  0xFF,    0xD9,    

NEXT) 

OPDEF(CEE̲SUB̲OVF,                    "sub.ovf",          Pop1+Pop1,     

Push1,       InlineNone,         IPrimitive,  1,  0xFF,    0xDA,    

NEXT) 

OPDEF(CEE̲SUB̲OVF̲UN,                 "sub.ovf.un",       Pop1+Pop1,   

Push1,       InlineNone,         IPrimitive,  1,  0xFF,    0xDB,    

NEXT) 

OPDEF(CEE̲ENDFINALLY,                 "endfinally",       Pop0,         

Push0,       InlineNone,         IPrimitive,  1,  0xFF,    0xDC,    

RETURN) 

OPDEF(CEE̲LEAVE,                      "leave",            Pop0,           

Push0,       InlineBrTarget,     IPrimitive,  1,  0xFF,    0xDD,    

BRANCH) 

OPDEF(CEE̲LEAVE̲S,                    "leave.s",          Pop0,           

Push0,       ShortInlineBrTarget,IPrimitive,  1,  0xFF,    0xDE,    

BRANCH) 

OPDEF(CEE̲STIND̲I,                    "stind.i",          PopI+PopI,     

Push0,       InlineNone,         IPrimitive,  1,  0xFF,    0xDF,    

NEXT) 

OPDEF(CEE̲CONV̲U,                     "conv.u",           Pop1,           

PushI,       InlineNone,         IPrimitive,  1,  0xFF,    0xE0,    

NEXT) 

OPDEF(CEE̲UNUSED26,                   "unused",           Pop0,           

Push0,       InlineNone,         IPrimitive,  1,  0xFF,    0xE1,    

NEXT) 

OPDEF(CEE̲UNUSED27,                   "unused",           Pop0,           

Push0,       InlineNone,         IPrimitive,  1,  0xFF,    0xE2,    

NEXT) 

OPDEF(CEE̲UNUSED28,                   "unused",           Pop0,           

Push0,       InlineNone,         IPrimitive,  1,  0xFF,    0xE3,    

NEXT) 

OPDEF(CEE̲UNUSED29,                   "unused",           Pop0,           

Push0,       InlineNone,         IPrimitive,  1,  0xFF,    0xE4,    

NEXT) 

OPDEF(CEE̲UNUSED30,                   "unused",           Pop0,           

440 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

Push0,       InlineNone,         IPrimitive,  1,  0xFF,    0xE5,    

NEXT) 

OPDEF(CEE̲UNUSED31,                   "unused",           Pop0,           

Push0,       InlineNone,         IPrimitive,  1,  0xFF,    0xE6,    

NEXT) 

OPDEF(CEE̲UNUSED32,                   "unused",           Pop0,           

Push0,       InlineNone,         IPrimitive,  1,  0xFF,    0xE7,    

NEXT) 

OPDEF(CEE̲UNUSED33,                   "unused",           Pop0,           

Push0,       InlineNone,         IPrimitive,  1,  0xFF,    0xE8,    

NEXT) 

OPDEF(CEE̲UNUSED34,                   "unused",           Pop0,           

Push0,       InlineNone,         IPrimitive,  1,  0xFF,    0xE9,    

NEXT) 

OPDEF(CEE̲UNUSED35,                   "unused",           Pop0,           

Push0,       InlineNone,         IPrimitive,  1,  0xFF,    0xEA,    

NEXT) 

OPDEF(CEE̲UNUSED36,                   "unused",           Pop0,           

Push0,       InlineNone,         IPrimitive,  1,  0xFF,    0xEB,    

NEXT) 

OPDEF(CEE̲UNUSED37,                   "unused",           Pop0,           

Push0,       InlineNone,         IPrimitive,  1,  0xFF,    0xEC,    

NEXT) 

OPDEF(CEE̲UNUSED38,                   "unused",           Pop0,           

Push0,       InlineNone,         IPrimitive,  1,  0xFF,    0xED,    

NEXT) 

OPDEF(CEE̲UNUSED39,                   "unused",           Pop0,           

Push0,       InlineNone,         IPrimitive,  1,  0xFF,    0xEE,    

NEXT) 

OPDEF(CEE̲UNUSED40,                   "unused",           Pop0,           

Push0,       InlineNone,         IPrimitive,  1,  0xFF,    0xEF,    

NEXT) 

OPDEF(CEE̲UNUSED41,                   "unused",           Pop0,           

Push0,       InlineNone,         IPrimitive,  1,  0xFF,    0xF0,    

NEXT) 

OPDEF(CEE̲UNUSED42,                   "unused",           Pop0,           

Push0,       InlineNone,         IPrimitive,  1,  0xFF,    0xF1,    

NEXT) 

OPDEF(CEE̲UNUSED43,                   "unused",           Pop0,           

Push0,       InlineNone,         IPrimitive,  1,  0xFF,    0xF2,    

441 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

NEXT) 

OPDEF(CEE̲UNUSED44,                   "unused",           Pop0,           

Push0,       InlineNone,         IPrimitive,  1,  0xFF,    0xF3,    

NEXT) 

OPDEF(CEE̲UNUSED45,                   "unused",           Pop0,           

Push0,       InlineNone,         IPrimitive,  1,  0xFF,    0xF4,    

NEXT) 

OPDEF(CEE̲UNUSED46,                   "unused",           Pop0,           

Push0,       InlineNone,         IPrimitive,  1,  0xFF,    0xF5,    

NEXT) 

OPDEF(CEE̲UNUSED47,                   "unused",           Pop0,           

Push0,       InlineNone,         IPrimitive,  1,  0xFF,    0xF6,    

NEXT) 

OPDEF(CEE̲UNUSED48,                   "unused",           Pop0,           

Push0,       InlineNone,         IPrimitive,  1,  0xFF,    0xF7,    

NEXT) 

OPDEF(CEE̲PREFIX7,                    "prefix7",          Pop0,           

Push0,       InlineNone,         IInternal,   1,  0xFF,    0xF8,    

META) 

OPDEF(CEE̲PREFIX6,                    "prefix6",          Pop0,           

Push0,       InlineNone,         IInternal,   1,  0xFF,    0xF9,    

META) 

OPDEF(CEE̲PREFIX5,                    "prefix5",          Pop0,           

Push0,       InlineNone,         IInternal,   1,  0xFF,    0xFA,    

META) 

OPDEF(CEE̲PREFIX4,                    "prefix4",          Pop0,           

Push0,       InlineNone,         IInternal,   1,  0xFF,    0xFB,    

META) 

OPDEF(CEE̲PREFIX3,                    "prefix3",          Pop0,           

Push0,       InlineNone,         IInternal,   1,  0xFF,    0xFC,    

META) 

OPDEF(CEE̲PREFIX2,                    "prefix2",          Pop0,           

Push0,       InlineNone,         IInternal,   1,  0xFF,    0xFD,    

META) 

OPDEF(CEE̲PREFIX1,                    "prefix1",          Pop0,           

Push0,       InlineNone,         IInternal,   1,  0xFF,    0xFE,    

META) 

OPDEF(CEE̲PREFIXREF,                  "prefixref",        Pop0,          

Push0,       InlineNone,         IInternal,   1,  0xFF,    0xFF,    

META) 

442 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

OPDEF(CEE̲ARGLIST,                    "arglist",          Pop0,           

PushI,       InlineNone,         IPrimitive,  2,  0xFE,    0x00,    

NEXT) 

OPDEF(CEE̲CEQ,                        "ceq",              Pop1+Pop1,      

PushI,       InlineNone,         IPrimitive,  2,  0xFE,    0x01,    

NEXT) 

OPDEF(CEE̲CGT,                        "cgt",              Pop1+Pop1,      

PushI,       InlineNone,         IPrimitive,  2,  0xFE,    0x02,    

NEXT) 

OPDEF(CEE̲CGT̲UN,                     "cgt.un",           Pop1+Pop1,     

PushI,       InlineNone,         IPrimitive,  2,  0xFE,    0x03,    

NEXT) 

OPDEF(CEE̲CLT,                        "clt",              Pop1+Pop1,      

PushI,       InlineNone,         IPrimitive,  2,  0xFE,    0x04,    

NEXT) 

OPDEF(CEE̲CLT̲UN,                     "clt.un",           Pop1+Pop1,     

PushI,       InlineNone,         IPrimitive,  2,  0xFE,    0x05,    

NEXT) 

OPDEF(CEE̲LDFTN,                      "ldftn",            Pop0,           

PushI,       InlineMethod,       IPrimitive,  2,  0xFE,    0x06,    

NEXT) 

OPDEF(CEE̲LDVIRTFTN,                  "ldvirtftn",        PopRef,       

PushI,       InlineMethod,       IPrimitive,  2,  0xFE,    0x07,    

NEXT) 

OPDEF(CEE̲UNUSED56,                   "unused",           Pop0,           

Push0,       InlineNone,         IPrimitive,  2,  0xFE,    0x08,    

NEXT) 

OPDEF(CEE̲LDARG,                      "ldarg",            Pop0,           

Push1,       InlineVar,          IPrimitive,  2,  0xFE,    0x09,    

NEXT) 

OPDEF(CEE̲LDARGA,                     "ldarga",           Pop0,           

PushI,       InlineVar,          IPrimitive,  2,  0xFE,    0x0A,    

NEXT) 

OPDEF(CEE̲STARG,                      "starg",            Pop1,           

Push0,       InlineVar,          IPrimitive,  2,  0xFE,    0x0B,    

NEXT) 

OPDEF(CEE̲LDLOC,                      "ldloc",            Pop0,           

Push1,       InlineVar,          IPrimitive,  2,  0xFE,    0x0C,    

NEXT) 

443 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

OPDEF(CEE̲LDLOCA,                     "ldloca",           Pop0,           

PushI,       InlineVar,          IPrimitive,  2,  0xFE,    0x0D,    

NEXT) 

OPDEF(CEE̲STLOC,                      "stloc",            Pop1,           

Push0,       InlineVar,          IPrimitive,  2,  0xFE,    0x0E,    

NEXT) 

OPDEF(CEE̲LOCALLOC,                   "localloc",         PopI,          

PushI,       InlineNone,         IPrimitive,  2,  0xFE,    0x0F,    

NEXT) 

OPDEF(CEE̲UNUSED57,                   "unused",           Pop0,           

Push0,       InlineNone,         IPrimitive,  2,  0xFE,    0x10,    

NEXT) 

OPDEF(CEE̲ENDFILTER,                  "endfilter",        PopI,          

Push0,       InlineNone,         IPrimitive,  2,  0xFE,    0x11,    

RETURN) 

OPDEF(CEE̲UNALIGNED,                  "unaligned.",       Pop0,          

Push0,       ShortInlineI,       IPrefix,     2,  0xFE,    0x12,    

META) 

OPDEF(CEE̲VOLATILE,                   "volatile.",        Pop0,          

Push0,       InlineNone,         IPrefix,     2,  0xFE,    0x13,    

META) 

OPDEF(CEE̲TAILCALL,                   "tail.",            Pop0,           

Push0,       InlineNone,         IPrefix,     2,  0xFE,    0x14,    

META) 

OPDEF(CEE̲INITOBJ,                    "initobj",          PopI,           

Push0,       InlineType,         IObjModel,   2,  0xFE,    0x15,    

NEXT) 

OPDEF(CEE̲UNUSED68,                   "unused",           Pop0,           

Push0,       InlineNone,         IPrimitive,  2,  0xFE,    0x16,    

NEXT) 

OPDEF(CEE̲CPBLK,                      "cpblk",            PopI+PopI+PopI, 

Push0,       InlineNone,         IPrimitive,  2,  0xFE,    0x17,    

NEXT) 

OPDEF(CEE̲INITBLK,                    "initblk",          

PopI+PopI+PopI,     Push0,       InlineNone,         IPrimitive,  2,  

0xFE,    0x18,    NEXT) 

OPDEF(CEE̲UNUSED69,                   "unused",           Pop0,           

Push0,       InlineNone,         IPrimitive,  2,  0xFE,    0x19,    

NEXT) 

OPDEF(CEE̲RETHROW,                    "rethrow",          Pop0,           

444 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

Push0,       InlineNone,         IObjModel,   2,  0xFE,    0x1A,    

THROW) 

OPDEF(CEE̲UNUSED51,                   "unused",           Pop0,           

Push0,       InlineNone,         IPrimitive,  2,  0xFE,    0x1B,    

NEXT) 

OPDEF(CEE̲SIZEOF,                     "sizeof",           Pop0,           

PushI,       InlineType,         IPrimitive,  2,  0xFE,    0x1C,    

NEXT) 

OPDEF(CEE̲REFANYTYPE,                 "refanytype",       Pop1,         

PushI,       InlineNone,         IPrimitive,  2,  0xFE,    0x1D,    

NEXT) 

OPDEF(CEE̲UNUSED52,                   "unused",           Pop0,          

Push0,       InlineNone,         IPrimitive,  2,  0xFE,    0x1E,    

NEXT) 

OPDEF(CEE̲UNUSED53,                   "unused",           Pop0,          

Push0,       InlineNone,         IPrimitive,  2,  0xFE,    0x1F,    

NEXT) 

OPDEF(CEE̲UNUSED54,                   "unused",           Pop0,          

Push0,       InlineNone,         IPrimitive,  2,  0xFE,    0x20,    

NEXT) 

OPDEF(CEE̲UNUSED55,                   "unused",           Pop0,           

Push0,       InlineNone,         IPrimitive,  2,  0xFE,    0x21,    

NEXT) 

OPDEF(CEE̲UNUSED70,                   "unused",           Pop0,           

Push0,       InlineNone,         IPrimitive,  2,  0xFE,    0x22,    

NEXT) 

// These are not real opcodes, but they are handy internally in the 

EE 

OPDEF(CEE̲ILLEGAL,                    "illegal",          Pop0,           

Push0,       InlineNone,         IInternal,   0,  MOOT,    MOOT,    

META) 

OPDEF(CEE̲MACRO̲END,                  "endmac",           Pop0,           

Push0,       InlineNone,         IInternal,   0,  MOOT,    MOOT,    

META) 

#ifndef OPALIAS 

background image

445 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

#define ̲OPALIAS̲DEFINED̲ 

#define OPALIAS(canonicalName, stringName, realOpcode) 

#endif 

OPALIAS(CEE̲BRNULL,        "brnull",            CEE̲BRFALSE) 

OPALIAS(CEE̲BRNULL̲S,      "brnull.s",          CEE̲BRFALSE̲S) 

OPALIAS(CEE̲BRZERO,        "brzero",            CEE̲BRFALSE) 

OPALIAS(CEE̲BRZERO̲S,      "brzero.s",          CEE̲BRFALSE̲S) 

OPALIAS(CEE̲BRINST,        "brinst",            CEE̲BRTRUE) 

OPALIAS(CEE̲BRINST̲S,      "brinst.s",          CEE̲BRTRUE̲S) 

OPALIAS(CEE̲LDIND̲U8,      "ldind.u8",          CEE̲LDIND̲I8) 

OPALIAS(CEE̲LDELEM̲U8,     "ldelem.u8",         CEE̲LDELEM̲I8) 

OPALIAS(CEE̲LDC̲I4̲M1x,    "ldc.i4.M1",         CEE̲LDC̲I4̲M1) 

OPALIAS(CEE̲ENDFAULT,      "endfault",          CEE̲ENDFINALLY) 

#ifdef ̲OPALIAS̲DEFINED̲ 

#undef OPALIAS 

#undef ̲OPALIAS̲DEFINED̲ 

#endif 

C.3 完全な文法 

この文法によって,第2章の文法では提供されない,多数の使いやすい機能が提供される。さらに,こ

の文法では,実装間での可搬性がないために,この規格には含まれない機能も提供している。この文法は,

第2章の文法とは異なり,読みやすさよりも容易なプログラムを目的として設計されており,YACC文法

に直接変換できる。 

Lexical tokens 

    ID - C style alphaNumeric identifier (e.g. Hello̲There2) 

    QSTRING  - C style quoted string (e.g.  "hi¥n") 

    SQSTRING - C style singlely quoted string(e.g.  'hi') 

    INT32    - C style 32 bit integer (e.g.  235,  03423, 0x34FFF) 

    INT64    - C style 64 bit integer (e.g.  -2353453636235234,  

0x34FFFFFFFFFF) 

    FLOAT64  - C style floating point number (e.g.  -0.2323, 354.3423, 

3435.34E-5) 

    INSTR̲*  - IL instructions of a particular class (see opcode.def). 

------------------------------------------------------------------

---------------- 

START           : decls 

                ;       

446 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

decls                   : /* EMPTY */ 

                        | decls decl                                           

                        ; 

decl                    : classHead '{' classDecls '}'  

                        | nameSpaceHead '{' decls '}'  

                        | methodHead  methodDecls '}'  

                        | fieldDecl 

                        | dataDecl 

                        | vtableDecl 

                        | vtfixupDecl 

                        | extSourceSpec 

                        | fileDecl 

                        | assemblyHead '{' assemblyDecls '}'  

                        | assemblyRefHead '{' assemblyRefDecls '}'  

                        | comtypeHead '{' comtypeDecls '}'  

                        | manifestResHead '{' manifestResDecls '}'  

                        | moduleHead 

                        | secDecl 

                        | customattrDecl 

  

| '.subsystem' int32  

  

| '.corflags' int32  

  

| '.file' 'alignment' int32  

  

| '.imagebase' int64  

  

| languageDecl 

                        ; 

compQstring             : QSTRING  

                        | compQstring '+' QSTRING  

  

languageDecl 

: '.language' SQSTRING 

                        | '.language' SQSTRING ',' SQSTRING 

                        | '.language' SQSTRING ',' SQSTRING ',' SQSTRING

  

  

customattrDecl          : '.custom' customType  

                        | '.custom' customType '=' compQstring  

                        | customHead bytes ')'  

447 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

                        | '.custom' '(' ownerType ')' customType  

                        | '.custom' '(' ownerType ')' customType '=' 

compQstring  

                        | customHeadWithOwner bytes ')'  

                        ; 

moduleHead              : '.module'  

                        | '.module' name1  

| '.module' 'extern' name1  

                        ; 

vtfixupDecl             : '.vtfixup' '[' int32 ']' vtfixupattr 'at' id  

                        ; 

vtfixupAttr             : /* EMPTY */  

                        | vtfixupAttr 'int32'  

                        | vtfixupAttr 'int64'  

                        | vtfixupAttr 'fromunmanaged'  

                        | vtfixupAttr 'callmostderived'  

                        ; 

vtableDecl              : vtableHead bytes ')'  

                        ; 

vtableHead              : '.vtable' '=' '('  

                        ; 

nameSpaceHead           : '.namespace' name1  

                        ; 

classHead               : '.class' classAttr id extendsClause implClause  

                        ; 

classAttr               : /* EMPTY */  

                        | classAttr 'public'  

                        | classAttr 'private'  

                        | classAttr 'value'  

                        | classAttr 'enum'  

                        | classAttr 'interface'  

                        | classAttr 'sealed'  

448 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

                        | classAttr 'abstract'  

                        | classAttr 'auto'  

                        | classAttr 'sequential'  

                        | classAttr 'explicit'  

                        | classAttr 'ansi'  

                        | classAttr 'unicode'  

                        | classAttr 'autochar'  

                        | classAttr 'import'  

                        | classAttr 'serializable'  

                        | classAttr 'nested' 'public'  

                        | classAttr 'nested' 'private'  

                        | classAttr 'nested' 'family'  

                        | classAttr 'nested' 'assembly'  

                        | classAttr 'nested' 'famandassem'  

                        | classAttr 'nested' 'famorassem'  

                        | classAttr 'beforefieldinit'  

                        | classAttr 'specialname'  

                        | classAttr 'rtspecialname'  

                        ; 

extendsClause           : /* EMPTY */                                       

                        | 'extends' className  

                        ; 

implClause              : /* EMPTY */ 

                        | 'implements' classNames 

                                                ; 

classNames              : classNames ',' className  

                        | className  

                        ; 

classDecls              : /* EMPTY */ 

                        | classDecls classDecl 

                        ; 

classDecl               : methodHead  methodDecls '}'  

                        | classHead '{' classDecls '}'  

                        | eventHead '{' eventDecls '}'  

                        | propHead '{' propDecls '}'  

449 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

                        | fieldDecl 

                        | dataDecl 

                        | secDecl 

                        | extSourceSpec 

                        | customAttrDecl 

                        | '.size' int32  

                        | '.pack' int32  

                        | exportHead '{' comtypeDecls '}'  

                        | '.override' typeSpec '::' methodName 'with' 

callConv type typeSpec '::' methodName '(' sigargs0 ')'  

  

| languageDecl 

                        ; 

fieldDecl               : '.field' repeatOpt fieldattr type id atOpt 

initOpt  

                        ; 

atOpt                   : /* EMPTY */   

                        | 'at' id  

                        ; 

initOpt                 : /* EMPTY */  

                        | '=' fieldInit  

repeatOpt  

: /* EMPTY */  

                        | '[' int32 ']'  

customHead              : '.custom' customType '=' '('  

                        ; 

customHeadWithOwner     : '.custom' '(' ownerType ')' customType '=' 

'('  

                        ; 

memberRef  

: methodSpec callConv type typeSpec 

'::' methodName '(' sigArgs0 ')'  

                        | methodSpec callConv type methodName '(' sigArgs0 

450 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

')'  

                        | 'field' type typeSpec '::' id  

                        | 'field' type id  

                        ; 

customType              : callConv type typeSpec '::' '.ctor' '(' sigArgs0 

')'  

                        | callConv type '.ctor' '(' sigArgs0 ')'  

                        ; 

ownerType               : typeSpec  

                        | memberRef  

                        ; 

eventHead               : '.event' eventAttr typeSpec id  

                        | '.event' eventAttr id  

                        ; 

eventAttr               : /* EMPTY */  

                        | eventAttr 'rtspecialname' /**/ 

                        | eventAttr 'specialname'  

                        ; 

eventDecls              : /* EMPTY */ 

                        | eventDecls eventDecl 

                        ; 

eventDecl               : '.addon' callConv type typeSpec '::' methodName 

'(' sigArgs0 ')'  

                        | '.addon' callConv type methodName '(' sigArgs0 

')'  

                        | '.removeon' callConv type typeSpec '::' 

methodName '(' sigArgs0 ')'  

                        | '.removeon' callConv type methodName '(' sigArgs0 

')'  

                        | '.fire' callConv type typeSpec '::' methodName 

'(' sigArgs0 ')'  

                        | '.fire' callConv type methodName '(' sigArgs0 

')'  

451 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

                        | '.other' callConv type typeSpec '::' methodName 

'(' sigArgs0 ')'  

                        | '.other' callConv type methodName '(' sigArgs0 

')'  

                        | extSourceSpec 

                        | customAttrDecl 

| languageDecl 

                        ; 

propHead                : '.property' propattr callConv type id '(' 

sigArgs0 ')' initOpt  

                        ; 

propAttr                : /* EMPTY */  

                        | propAttr 'rtspecialname' /**/ 

                        | propAttr 'specialname'  

                        ; 

propDecls               : /* EMPTY */ 

                        | propDecls propDecl 

                        ; 

propDecl                : '.set' callConv type typeSpec '::' methodName 

'(' sigArgs0 ')'  

                        | '.set' callConv type methodName '(' sigArgs0 ')'  

                        | '.get' callConv type typeSpec '::' methodName 

'(' sigArgs0 ')'  

                        | '.get' callConv type methodName '(' sigArgs0 ')'  

                        | '.other' callConv type typeSpec '::' methodName 

'(' sigArgs0 ')'  

                        | '.other' callConv type methodName '(' sigArgs0 

')'  

                        | customAttrDecl 

                        | extSourceSpec 

  

| languageDecl 

                        ; 

methodHeadPart1         : '.method'  

452 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

                        ; 

methodHead              : methodHeadPart1 methAttr callConv paramAttr 

type methodName '(' sigArgs0 ')' implAttr '{'  

                        | methodHeadPart1 methAttr callConv paramAttr type 

'marshal' '(' nativeType ')' methodName '(' sigArgs0 ')' implAttr '{'  

                        ; 

methAttr                : /* EMPTY */  

                        | methAttr 'static'  

                        | methAttr 'public'  

                        | methAttr 'private'  

                        | methAttr 'family'  

                        | methAttr 'final'  

                        | methAttr 'specialname'  

                        | methAttr 'virtual'  

                        | methAttr 'abstract'  

                        | methAttr 'assembly'  

                        | methAttr 'famandassem'  

                        | methAttr 'famorassem'  

                        | methAttr 'privatescope'  

                        | methAttr 'hidebysig'  

                        | methAttr 'newslot'  

                        | methAttr 'rtspecialname' /**/ 

                        | methAttr 'unmanagedexp'  

                        | methAttr 'reqsecobj'  

  

                        | methAttr 'pinvokeimpl' '(' compQstring 'as' 

compQstring pinvAttr ')'  

                        | methAttr 'pinvokeimpl' '(' compQstring  pinvAttr 

')'  

                        | methAttr 'pinvokeimpl' '(' pinvAttr ')'  

                        ; 

pinvAttr                : /* EMPTY */  

                        | pinvAttr 'nomangle'  

                        | pinvAttr 'ansi'  

                        | pinvAttr 'unicode'  

                        | pinvAttr 'autochar'  

453 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

                        | pinvAttr 'lasterr'  

                        | pinvAttr 'winapi'  

                        | pinvAttr 'cdecl'  

                        | pinvAttr 'stdcall'  

                        | pinvAttr 'thiscall'  

                        | pinvAttr 'fastcall'  

                        ; 

methodName              : '.ctor'  

                        | '.cctor'  

                        | name1  

                        ; 

paramAttr               : /* EMPTY */  

                        | paramAttr '[' 'in' ']'  

                        | paramAttr '[' 'out' ']'  

                        | paramAttr '[' 'opt' ']'  

                        | paramAttr '[' int32 ']'   

                        ; 

         

fieldAttr               : /* EMPTY */  

                        | fieldAttr 'static'  

                        | fieldAttr 'public'  

                        | fieldAttr 'private'  

                        | fieldAttr 'family'  

                        | fieldAttr 'initonly'  

                        | fieldAttr 'rtspecialname'  /**/ 

                        | fieldAttr 'specialname'  

/* commented out because 

PInvoke for fields is not supported by EE 

                        | fieldAttr 'pinvokeimpl' '(' compQstring 'as' 

compQstring pinvAttr ')'  

                        | fieldAttr 'pinvokeimpl' '(' compQstring  

pinvAttr ')'  

                        | fieldAttr 'pinvokeimpl' '(' pinvAttr ')'  

*/ 

                        | fieldAttr 'marshal' '(' nativeType ')'  

                        | fieldAttr 'assembly'  

                        | fieldAttr 'famandassem'  

                        | fieldAttr 'famorassem'  

454 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

                        | fieldAttr 'privatescope'  

                        | fieldAttr 'literal'  

                        | fieldAttr 'notserialized'  

                        ; 

implAttr                : /* EMPTY */  

                        | implAttr 'native'  

                        | implAttr 'cil'  

                        | implAttr 'optil'  

                        | implAttr 'managed'  

                        | implAttr 'unmanaged'  

                        | implAttr 'forwardref'  

                        | implAttr 'preservesig'  

                        | implAttr 'runtime'  

                        | implAttr 'internalcall'  

                        | implAttr 'synchronized'  

                        | implAttr 'noinlining'  

                        ; 

localsHead              : '.locals'  

                        ; 

methodDecl              : '.emitbyte' int32  

                        | sehBlock  

                        | '.maxstack' int32  

                        | localsHead '(' sigArgs0 ')'  

                        | localsHead 'init' '(' sigArgs0 ')'  

                        | '.entrypoint'  

                        | '.zeroinit'  

                        | dataDecl 

                        | instr 

                        | id ':'  

                        | secDecl 

                        | extSourceSpec 

  

| languageDecl 

                        | customAttrDecl 

  

| '.export' '[' int32 ']' 

  

| '.export' '[' int32 ']'

 'as' id  

455 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

                        | '.vtentry' int32 ':' int32  

                        | '.override' typeSpec '::' methodName  

                        | scopeBlock 

                        | '.param' '[' int32 ']' initOpt  

                        ; 

scopeBlock              : scopeOpen methodDecls '}'  

                        ; 

scopeOpen               : '{'  

                        ; 

sehBlock                : tryBlock sehClauses 

                        ; 

sehClauses              : sehClause sehClauses 

                        | sehClause 

                        ; 

tryBlock                : tryHead scopeBlock  

                        | tryHead id 'to' id  

                        | tryHead int32 'to' int32  

                        ; 

tryHead                 : '.try'  

                        ; 

sehClause               : catchClause handlerBlock  

                        | filterClause handlerBlock  

                        | finallyClause handlerBlock  

                        | faultClause handlerBlock  

                        ; 

                                                                                 

filterClause            : filterHead scopeBlock  

                        | filterHead id  

                        | filterHead int32  

                        ; 

456 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

filterHead              : 'filter'   

                        ; 

catchClause             : 'catch' className  

                        ; 

finallyClause           : 'finally'  

                        ; 

faultClause             : 'fault'  

                        ; 

handlerBlock            : scopeBlock                   

                        | 'handler' id 'to' id  

                        | 'handler' int32 'to' int32  

                        ; 

methodDecls             : /* EMPTY */ 

                        | methodDecls methodDecl 

                        ; 

dataDecl                : ddHead ddBody 

                        ; 

ddHead                  : '.data' tls id '='  

                        | '.data' tls   

                        ; 

tls                     : /* EMPTY */  

                        | 'tls'  

                        ; 

ddBody                  : '{' ddItemList '}' 

                        | ddItem 

                        ; 

ddItemList              : ddItem ',' ddItemList 

                        | ddItem 

                        ; 

457 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

ddItemCount             : /* EMPTY */  

                        | '[' int32 ']'  

                        ; 

ddItem                  : 'char' '*' '(' compQstring ')'  

                        | '&' '(' id ')'  

                        | bytearrayhead bytes ')'  

                        | 'float32' '(' float64 ')' ddItemCount  

                        | 'float64' '(' float64 ')' ddItemCount  

                        | 'int64' '(' int64 ')' ddItemCount   

                        | 'int32' '(' int32 ')' ddItemCount   

                        | 'int16' '(' int32 ')' ddItemCount  

                        | 'int8' '(' int32 ')' ddItemCount  

                        | 'float32' ddItemCount  

                        | 'float64' ddItemCount  

                        | 'int64' ddItemCount   

                        | 'int32' ddItemCount   

                        | 'int16' ddItemCount  

                        | 'int8' ddItemCount  

                        ; 

fieldInit               : 'float32' '(' float64 ')'  

                        | 'float64' '(' float64 ')'  

                        | 'float32' '(' int64 ')'  

                        | 'float64' '(' int64 ')'  

                        | 'int64' '(' int64 ')'   

                        | 'int32' '(' int64 ')'  

                        | 'int16' '(' int64 ')'  

                        | 'char' '(' int64 ')'  

                        | 'int8' '(' int64 ')'  

                        | 'bool' '(' truefalse ')'  

                        | compQstring  

                        | bytearrayhead bytes ')'  

| 'nullref'  

                        ; 

bytearrayhead           : 'bytearray' '('  

                        ; 

458 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

bytes 

: /* EMPTY */  

| hexbytes  

  

hexbytes                : HEXBYTE  

                        | hexbytes HEXBYTE  

                        ; 

instr̲r̲head            : INSTR̲R '('  

                        ; 

instr̲tok̲head          : INSTR̲TOK  

                        ; 

methodSpec              : 'method'  

                        ; 

instr                   : INSTR̲NONE  

                        | INSTR̲VAR int32  

                        | INSTR̲VAR id  

                        | INSTR̲I int32  

                        | INSTR̲I8 int64  

                        | INSTR̲R float64  

                        | INSTR̲R int64  

                        | instr̲r̲head bytes ')'  

                        | INSTR̲BRTARGET int32  

                        | INSTR̲BRTARGET id  

                        | INSTR̲METHOD callConv type typeSpec '::' 

methodName '(' sigArgs0 ')'  

                        | INSTR̲METHOD callConv type methodName '(' 

sigArgs0 ')'  

                        | INSTR̲FIELD type typeSpec '::' id  

                        | INSTR̲FIELD type id  

                        | INSTR̲TYPE typeSpec  

                        | INSTR̲STRING compQstring  

                        | INSTR̲STRING bytearrayhead bytes ')'  

                        | INSTR̲SIG callConv type '(' sigArgs0 ')'  

                        | INSTR̲RVA id  

                        | INSTR̲RVA int32  

                        | instr̲tok̲head ownerType /* ownerType ::= 

459 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

memberRef | typeSpec */  

                        | INSTR̲SWITCH '(' labels ')'  

                        | INSTR̲PHI int16s  

                        ; 

sigArgs0                : /* EMPTY */  

                        | sigArgs1  

                        ; 

sigArgs1                : sigArg  

                        | sigArgs1 ',' sigArg  

                        ; 

sigArg                  : '...'  

                        | paramAttr type  

                        | paramAttr type id  

                        | paramAttr type 'marshal' '(' nativeType ')'  

                        | paramAttr type 'marshal' '(' nativeType ')' id  

                        ; 

name1                   : id  

                        | DOTTEDNAME  

                        | name1 '.' name1  

                        ; 

className               : '[' name1 ']' slashedName  

                        | '[' '.module' name1 ']' slashedName  

                        | slashedName  

                        ; 

slashedName             : name1  

                        | slashedName '/' name1  

                        ; 

typeSpec                : className  

                        | '[' name1 ']'  

                        | '[' '.module' name1 ']'  

                        | type  

                        ; 

460 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

callConv                : 'instance' callConv  

                        | 'explicit' callConv  

                        | callKind  

                        ; 

callKind                : /* EMPTY */  

                        | 'default'  

                        | 'vararg'  

                        | 'unmanaged' 'cdecl'  

                        | 'unmanaged' 'stdcall'  

                        | 'unmanaged' 'thiscall'  

                        | 'unmanaged' 'fastcall'  

                        ; 

nativeType              : /* EMPTY */   

                        | 'custom' '(' compQstring ',' compQstring ',' 

compQstring ',' compQstring ')'  

                        | 'custom' '(' compQstring ',' compQstring ')'  

                        | 'fixed' 'sysstring' '[' int32 ']'  

                        | 'fixed' 'array' '[' int32 ']'  

                        | 'variant'  

                        | 'currency'  

                        | 'syschar'  

                        | 'void'  

                        | 'bool'  

                        | 'int8'  

                        | 'int16'  

                        | 'int32'  

                        | 'int64'  

                        | 'float32'  

                        | 'float64'  

                        | 'error'  

                        | 'unsigned' 'int8'  

                        | 'unsigned' 'int16'  

                        | 'unsigned' 'int32'  

                        | 'unsigned' 'int64'  

                        | nativeType '*'  

                        | nativeType '[' ']'  

                        | nativeType '[' int32 ']'  

                        | nativeType '[' int32 '+' int32 ']'  

461 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

                        | nativeType '[' '+' int32 ']'  

  

| 'decimal'  

                        | 'date'  

                        | 'bstr'  

                        | 'lpstr'  

                        | 'lpwstr'  

                        | 'lptstr'  

                        | 'objectref'  

                        | 'iunknown'  

                        | 'idispatch'  

                        | 'struct'  

                        | 'interface'  

                        | 'safearray' variantType  

                        | 'safearray' variantType ',' compQstring  

                                                                 

                        | 'int'  

                        | 'unsigned' 'int'  

                        | 'nested' 'struct'  

                        | 'byvalstr'  

                        | 'ansi' 'bstr'  

                        | 'tbstr'  

                        | 'variant' 'bool'  

                        | methodSpec  

                        | 'as' 'any'  

                        | 'lpstruct'  

                        ; 

variantType             : /* EMPTY */  

                        | 'null'  

                        | 'variant'  

                        | 'currency'  

                        | 'void'  

                        | 'bool'  

                        | 'int8'  

                        | 'int16'  

                        | 'int32'  

                        | 'int64'  

                        | 'float32'  

                        | 'float64'  

                        | 'unsigned' 'int8'  

462 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

                        | 'unsigned' 'int16'  

                        | 'unsigned' 'int32'  

                        | 'unsigned' 'int64'  

                        | '*'  

                        | variantType '[' ']'  

                        | variantType 'vector'  

                        | variantType '&'  

                        | 'decimal'  

                        | 'date'  

                        | 'bstr'  

                        | 'lpstr'  

                        | 'lpwstr'  

                        | 'iunknown'  

                        | 'idispatch'  

                        | 'safearray'  

                        | 'int'  

                        | 'unsigned' 'int'  

                        | 'error'  

                        | 'hresult'  

                        | 'carray'  

                        | 'userdefined'  

                        | 'record'  

                        | 'filetime'  

                        | 'blob'  

                        | 'stream'  

                        | 'storage'  

                        | 'streamed̲object'  

                        | 'stored̲object'  

                        | 'blob̲object'  

                        | 'cf'  

                        | 'clsid'  

                        ; 

type                    : 'class' className   

  

| 'object'   

  

| 'string'   

                        | 'value' 'class' className   

                        | 'valuetype' className   

                        | type '[' ']'   

                        | type '[' bounds1 ']'   

463 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

  

/* uncomment when and if this 

type is supported by the Runtime 

                        | type 'value' '[' int32 ']'  

                        */ 

  

| type '&'  

                        | type '*'  

                        | type 'pinned'  

                        | type 'modreq' '(' className ')'  

                        | type 'modopt' '(' className ')'  

                        | '!' int32  

                        | methodSpec callConv type '*' '(' sigArgs0 ')'  

                        | 'typedref'  

                        | 'char'  

                        | 'void'  

                        | 'bool'  

                        | 'int8'  

                        | 'int16'  

                        | 'int32'  

                        | 'int64'  

                        | 'float32'  

                        | 'float64'  

                        | 'unsigned' 'int8'  

                        | 'unsigned' 'int16'  

                        | 'unsigned' 'int32'  

                        | 'unsigned' 'int64'  

                        | 'native' 'int'  

                        | 'native' 'unsigned' 'int'  

                        | 'native' 'float'  

                        ; 

bounds1                 : bound  

                        | bounds1 ',' bound  

                        ; 

bound                   : /* EMPTY */  

                        | '...'  

                        | int32   

                        | int32 '...' int32     

                        | int32 '...'   

                        ; 

464 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

labels                  : /* empty */  

                        | id ',' labels  

                        | int32 ',' labels  

                        | id  

                        | int32  

                        ; 

id                      : ID  

                        | SQSTRING  

                        ; 

int16s                  : /* EMPTY */  

                        | int16s int32  

                        ; 

                                 

int32                   : INT64  

                        ; 

int64                   : INT64  

                        ; 

float64                 : FLOAT64  

                        | 'float32' '(' int32 ')'  

                        | 'float64' '(' int64 ')'  

                        ; 

secDecl                 : '.permission' secAction typeSpec '(' 

nameValPairs ')'  

                        | '.permission' secAction typeSpec  

                        | psetHead bytes ')'  

                        ; 

psetHead                : '.permissionset' secAction '=' '('  

                        ; 

nameValPairs            : nameValPair  

                        | nameValPair ',' nameValPairs  

                        ; 

465 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

nameValPair             : compQstring '=' caValue  

                        ; 

truefalse  

: 'true'  

  

| 'false'  

caValue                 : truefalse  

                        | int32  

                        | 'int32' '(' int32 ')'  

                        | compQstring  

                        | className '(' 'int8' ':' int32 ')'  

                        | className '(' 'int16' ':' int32 ')'  

                        | className '(' 'int32' ':' int32 ')'  

                        | className '(' int32 ')'  

                        ; 

secAction               : 'request'  

                        | 'demand'  

                        | 'assert'  

                        | 'deny'  

                        | 'permitonly'  

                        | 'linkcheck'  

                        | 'inheritcheck'  

                        | 'reqmin'  

                        | 'reqopt'  

                        | 'reqrefuse'  

                        | 'prejitgrant'  

                        | 'prejitdeny'  

                        | 'noncasdemand'  

                        | 'noncaslinkdemand'  

                        | 'noncasinheritance'  

                        ; 

extSourceSpec           : '.line' int32 SQSTRING  

                        | '.line' int32  

                        | '.line' int32 ':' int32 SQSTRING  

                        | '.line' int32 ':' int32  

                        | P̲LINE int32 QSTRING  

466 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

                        ; 

fileDecl                : '.file' fileAttr name1 fileEntry hashHead bytes 

')' fileEntry  

                        | '.file' fileAttr name1 fileEntry  

                        ; 

fileAttr                : /* EMPTY */  

                        | fileAttr 'nometadata'  

                        ; 

fileEntry               : /* EMPTY */  

                        | '.entrypoint'  

                        ; 

hashHead                : '.hash' '=' '('  

                        ; 

assemblyHead            : '.assembly' asmattr name1  

                        ; 

asmAttr                 : /* EMPTY */  

                        | asmAttr 'noappdomain'  

                        | asmAttr 'noprocess'  

                        | asmAttr 'nomachine'  

                        ; 

assemblyDecls           : /* EMPTY */ 

                        | assemblyDecls assemblyDecl 

                        ; 

assemblyDecl            : '.hash' 'algorithm' int32  

                        | secDecl 

                        | asmOrRefDecl 

                        ; 

asmOrRefDecl            : publicKeyHead bytes ')'  

                        | '.ver' int32 ':' int32 ':' int32 ':' int32  

                        | '.locale' compQstring  

                        | localeHead bytes ')'  

467 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

                        | customAttrDecl 

                        ; 

publicKeyHead           : '.publickey' '=' '('  

                        ; 

publicKeyTokenHead      : '.publickeytoken' '=' '('  

                        ; 

localeHead              : '.locale' '=' '('  

                        ; 

assemblyRefHead         : '.assembly' 'extern' name1  

                        | '.assembly' 'extern' name1 'as' name1  

                        ; 

assemblyRefDecls        : /* EMPTY */ 

                        | assemblyRefDecls assemblyRefDecl 

                        ; 

assemblyRefDecl         : hashHead bytes ')'  

                        | asmOrRefDecl 

                        | publicKeyTokenHead bytes ')'  

                        ; 

comtypeHead             : '.class' 'extern' comtAttr name1   

                        ; 

exportHead              : '.export' comtAttr name1  

                        ; 

comtAttr                : /* EMPTY */  

                        | comtAttr 'private'  

                        | comtAttr 'public'  

                        | comtAttr 'nested' 'public'  

                        | comtAttr 'nested' 'private'  

                        | comtAttr 'nested' 'family'  

                        | comtAttr 'nested' 'assembly'  

                        | comtAttr 'nested' 'famandassem'  

                        | comtAttr 'nested' 'famorassem'  

background image

468 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

                        ; 

comtypeDecls            : /* EMPTY */ 

                        | comtypeDecls comtypeDecl 

                        ; 

comtypeDecl             : '.file' name1  

                        | '.class' 'extern' name1  

                        | '.class'  int32  

                        | customAttrDecl 

                        ; 

manifestResHead         : '.mresource' manresAttr name1  

                        ; 

manresAttr              : /* EMPTY */  

                        | manresAttr 'public'  

                        | manresAttr 'private'  

                        ; 

manifestResDecls        : /* EMPTY */ 

                        | manifestResDecls manifestResDecl 

                        ; 

manifestResDecl         : '.file' name1 'at' int32  

                        | '.assembly' 'extern' name1  

                        | customAttrDecl 

                        ; 

C.4 命令構文 

C.4の各細分箇条では,文法クラスに含まれる命令の厳密なリストが指定されるが,この情報は時間の

経過とともに変化する。命令の正確な書式は,次の表に記載された情報とC.1の情報とを組み合わせるこ

とで確認できる。 

表1−命令構文のクラス 

文法クラス 

C.1で指定した書式 

<instr̲brtarget> 

InlineBrTarget, ShortInlineBrTarget 

<instr̲field> 

InlineField 

<instr̲i> 

InlineI, ShortInlineI 

<instr̲i8> 

InlineI8 

<instr̲method> 

InlineMethod 

<instr̲none> 

InlineNone 

469 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

<instr̲phi> 

InlinePhi 

<instr̲r> 

InlineR, ShortInlineR 

<instr̲rva> 

InlineRVA 

<instr̲sig> 

InlineSig 

<instr̲string> 

InlineString 

<instr̲switch> 

InlineSwitch 

<instr̲tok> 

InlineTok 

<instr̲type> 

InlineType 

<instr̲var> 

InlineVar, ShortInlineVar 

C.4.1 最上位の命令構文 

<instr> ::= 

    <instr̲brtarget> <int32> 

  | <instr̲brtarget> <label> 

  | <instr̲field> <type> [ <typeSpec> :: ] <id> 

  | <instr̲i> <int32> 

  | <instr̲i8> <int64> 

  | <instr̲method> 

      <callConv> <type> [ <typeSpec> :: ] 

<methodName> ( <parameters> ) 

  | <instr̲none> 

  | <instr̲phi> <int16>* 

  | <instr̲r> ( <bytes> ) 

// <bytes> represent the binary image 

of 

// float or double (4 or 8 bytes, 

// respectively) 

  | <instr̲r> <float64> 

  | <instr̲r> <int64> 

// integer is converted to float 

// with possible 

// loss of precision 

  | <instr̲sig> <callConv> <type> ( <parameters> )  

  | <instr̲string> bytearray ( <bytes> ) 

  | <instr̲string> <QSTRING> 

  | <instr̲switch> ( <labels> ) 

  | <instr̲tok> field <type> [ <typeSpec> :: ] <id> 

  | <instr̲tok> b 

      <callConv> <type> [ <typeSpec> :: ] 

<methodName> ( <parameters> ) 

  | <instr̲tok> <typeSpec> 

  | <instr̲type> <typeSpec> 

  | <instr̲var> <int32> 

  | <instr̲var> <localname> 

470 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

C.4.2 演算対象が設定されていない命令 

こうした命令は演算対象を必要としない。したがって,命令自体が表示されるだけである。 

<instr> ::= <instr̲none> 

<instr̲none> ::= // Derived from opcode.def 

   add              | add.ovf     | add.ovf.un     | and        | 

   arglist         | break       | ceq            | cgt        | 

   cgt.un          | ckfinite    | clt            | clt.un     | 

   conv.i          | conv.i1     | conv.i2        | conv.i4    | 

   conv.i8          | conv.ovf.i  | conv.ovf.i.un  | conv.ovf.i1| 

   conv.ovf.i1.un | conv.ovf.i2 | conv.ovf.i2.un | conv.ovf.i4| 

   conv.ovf.i4.un | conv.ovf.i8 | conv.ovf.i8.un | conv.ovf.u | 

   conv.ovf.u.un  | conv.ovf.u1 | conv.ovf.u1.un | conv.ovf.u2| 

   conv.ovf.u2.un | conv.ovf.u4 | conv.ovf.u4.un | conv.ovf.u8| 

   conv.ovf.u8.un | conv.r.un   | conv.r4        | conv.r8    | 

   conv.u         | conv.u1     | conv.u2        | conv.u4    | 

   conv.u8        | cpblk       | div            | div.un     | 

   dup            | endfault    | endfilter      | endfinally | 

   initblk        |             | ldarg.0        | ldarg.1    |   

   ldarg.2        | ldarg.3     | ldc.i4.0       | ldc.i4.1   |    

   ldc.i4.2       | ldc.i4.3    | ldc.i4.4       | ldc.i4.5   | 

   ldc.i4.6       | ldc.i4.7    | ldc.i4.8       | ldc.i4.M1  | 

   ldelem.i       | ldelem.i1   | ldelem.i2      | ldelem.i4  | 

   ldelem.i8      | ldelem.r4   | ldelem.r8      | ldelem.ref | 

   ldelem.u1      | ldelem.u2   | ldelem.u4      | ldind.i    | 

   ldind.i1       | ldind.i2    | ldind.i4       | ldind.i8   | 

   ldind.r4       | ldind.r8    | ldind.ref      | ldind.u1   | 

   ldind.u2       | ldind.u4    | ldlen          | ldloc.0    | 

   ldloc.1        | ldloc.2     | ldloc.3        | ldnull     | 

   localloc       | mul         | mul.ovf        | mul.ovf.un | 

   neg            | nop         | not            | or         | 

   pop            | refanytype  | rem            | rem.un     | 

   ret            | rethrow     | shl            | shr        | 

   shr.un         | stelem.i    | stelem.i1      | stelem.i2  | 

   stelem.i4      | stelem.i8   | stelem.r4      | stelem.r8  | 

   stelem.ref     | stind.i     | stind.i1       | stind.i2   | 

   stind.i4       | stind.i8    | stind.r4       | stind.r8   | 

   stind.ref      | stloc.0     | stloc.1        | stloc.2    | 

   stloc.3        | sub         | sub.ovf        | sub.ovf.un | 

   tail.          | throw       | volatile.      | xor 

471 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

例 

ldlen 

not 

C.4.3 仮引数又は局所変数を参照する命令 

こうした命令は一つの演算対象をとるが,この演算対象は現在のメソッドの仮引数又は局所変数を参照

する。この変数は,その数値(変数0で開始。)又は名前(型及び名前の両方を提供するフォームを利用し

ている識別情報の一部として名前が提供されている場合。)によって参照できる。 

<instr> ::= <instr̲var> <int32> | 

            <instr̲var> <localname> 

<instr̲var> ::= // Derived from opcode.def 

          | ldarg    | ldarg.s  | ldarga 

ldarga.s  | ldloc    | ldloc.s  | ldloca 

ldloca.s  | starg    | starg.s  | stloc 

stloc.s 

例 

stloc 0          // store into 0th local 

ldarg X3         // load from argument named X3 

C.4.4 単一の32ビット整数の実引数をとる命令 

こうした命令は一つの演算対象をとる。この演算対象は32ビット整数でなければならない。 

<instr> ::= <instr̲i> <int32> 

<instr̲i> ::= // Derived from opcode.def 

ldc.i4 | ldc.i4.s | unaligned. 

例 

ldc.i4 123456  // Load the number 123456 

ldc.i4.s 10    // Load the number 10 

C.4.5 単一の64ビット整数の実引数をとる命令 

こうした命令は一つの演算対象をとる。この演算対象は64ビット整数でなければならない。 

<instr> ::= <instr̲i8> <int64> 

<instr̲i8> ::= // Derived from opcode.def 

ldc.i8 

例 

ldc.i8 0x123456789AB 

ldc.i8 12 

472 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

C.4.6 単一の浮動小数点の実引数をとる命令 

こうした命令は一つの演算対象をとる。この演算対象は浮動小数点数でなければならない。 

<instr> ::= <instr̲r> <float64> | 

              <instr̲r> <int64>   | 

  

<instr̲r> ( <bytes> )  // <bytes> is binary image 

<instr̲r> ::= // Derived from opcode.def 

ldc.r4 | ldc.r8 

例 

ldc.r4 10.2 

ldc.r4 10 

ldc.r4 0x123456789ABCDEF 

ldc.r8 (00 00 00 00 00 00 F8 FF) 

C.4.7 分岐命令 

アセンブラは分岐を最適化しない。分岐は,短形式の命令又は長形式の命令のいずれを使用するか明示

的に指定する必要がある。短形式では変位が大きすぎる場合,アセンブラによってエラーが表示される。 

<instr> ::= 

  

<instr̲brtarget> <int32> | 

  

<instr̲brtarget> <label> 

<instr̲brtarget> ::= // Derived from opcode.def 

  

| beq  

| beq.s | bge | bge.s 

 | 

 bge.un | bge.un.s 

| bgt  

| bgt.s | bgt.un | 

 bgt.un.s | 

 ble 

| ble.s | ble.un 

| ble.un.s 

| blt | blt.s 

 | 

 blt.un | blt.un.s 

| bne.un 

| bne.un.s 

| br 

| br.s 

 | 

 brfalse| brfalse.s 

| brtrue 

| brtrue.s 

| leave | 

 leave.s 

例 

br.s 22 

br foo 

C.4.8 実引数としてメソッドをとる命令 

こうした命令は,他のクラス(最初の命令書式。)又は現在のクラス(2番目の命令書式。)のいずれか

にあるメソッドを参照する。 

<instr> ::= 

473 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

   <instr̲method> 

     <callConv> <type> [ <typeSpec> :: ] <methodName> ( <parameters> ) 

<instr̲method> ::= // Derived from opcode.def 

     call  | callvirt | jmp | ldftn    | ldvirtftn        | newobj 

例 

call instance int32 C.D.E::X(class W, native int) 

ldftn vararg char F(...) 

// Global Function F 

C.4.9 実引数としてクラスのフィールドをとる命令 

こうした命令はクラスのフィールドを参照する。 

<instr> ::= 

  

<instr̲field> <type> <typeSpec> :: <id> 

<instr̲field> ::= // Derived from opcode.def 

  

ldfld | ldflda | ldsfld | ldsflda | stfld | stsfld 

例 

ldfld native int X::IntField 

stsfld int32 Y::AnotherField 

C.4.10 実引数として型をとる命令 

こうした命令は型を参照する。 

<instr> ::= <instr̲type> <typeSpec> 

<instr̲type> ::= // Derived from opcode.def 

 box 

| castclass 

| cpobj | initobj 

| isinst | 

 ldelema | ldobj | mkrefany 

| newarr 

| refanyv | 

 sizeof | stobj | unbox 

例 

initobj [mscorlib]System.Console 

sizeof class X 

C.4.11 実引数として文字列をとる命令 

こうした命令は実引数として文字列をとる。 

<instr> ::= <instr̲string> <QSTRING> 

<instr̲string> ::= // Derived from opcode.def 

  

ldstr 

例 

ldstr “This is a string” 

474 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

ldstr “This has a¥nnewline in it” 

C.4.12 実引数として識別情報をとる命令 

こうした命令は,実引数としてスタンドアロン識別情報をとる。 

<instr> ::= <instr̲sig> <callConv> <type> ( <parameters> ) 

<instr̲sig> ::= // Derived from opcode.def 

  

calli 

例 

calli class A.B(wchar *) 

calli vararg bool(int32[,] X, ...) 

// Returns a boolean, takes at least one argument. The first 

// argument, named X, must be a two-dimensional array of 

// 32-bit ints 

C.4.13 実引数としてメタデータトークンをとる命令 

この命令は,実引数としてメタデータトークンをとる。このトークンは,クラスの型,メソッド,又は

フィールドを参照できる。 

<instr> ::= <instr̲tok> <typeSpec> | 

            <instr̲tok> method 

               <callConv> <type> <typeSpec> :: <methodName> 

                          ( <parameters> ) | 

            <instr̲tok> method 

               <callConv> <type> <methodName> 

                          ( <parameters> ) | 

            <instr̲tok> field <type> <typeSpec> :: <id> 

<instr̲tok> ::= // Derived from opcode.def 

  

ldtoken 

例 

ldtoken class [mscorlib]System.Console 

ldtoken method int32 X::Fn() 

ldtoken method bool GlobalFn(int32 &) 

ldtoken field class X.Y Class::Field 

C.4.14 Switch命令 

switch命令は,一連のラベル又は10進数の相対値をとる。 

<instr> ::= <instr̲switch> ( <labels> ) 

<instr̲switch> ::= // Derived from opcode.def 

  

switch 

475 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

例 

switch (0x3, -14, Label1) 

switch (5, Label2) 

476 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

附属書D 
(参考) 

クラスライブラリの設計ガイドライン 

注記 附属書Dでは参考情報だけを示す。 

この話題に関する情報は次の場所にある。 

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpgenref/html/cpconnetframeworkdesignguidelines.

asp 

477 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

附属書E 

(参考) 

可搬性に関する考察 

ここでは,この規格において実装に関する余地が残された領域について説明する。こうした余地を利用

することによって,規格適合処理系において,他の方法でより優れた性能を提供したり,価値を追加した

りすることを選択できるようになる。しかし,こうした余地は,本質的にプログラムの可搬性を低める結

果になる。ここでは,CLIの特定の実装に依存することなく,プログラムを同じように確実に動作させる

ために利用できる手法について説明する。 

整数型の大きさ及びワード内でのバイト方向が原因でデータに可搬性がない場合でも,コードは可搬で

あることに注意する。読込みメソッドが書出しメソッドに対応する場合,読込み/書出しの不変性が保持

される(すなわち,整数型として書き出したデータは整数型として読み込むことができるが,文字列型と

して書き出したデータを整数型として読み込むことはできない場合がある。)。 

E.1 

制御できない振る舞い 

次に挙げるプログラムの振る舞いは実装に依存する。こうした項目の多くは,可搬性のために設計され

たコードの記述に従事するプログラマにはよく知られている(例えば,CLIでは,ヒープ又はスタックの

大きさに最小サイズが設定されない。)。 

1) ヒープ及びスタックの大きさには,必ずしも最小サイズを設定する必要はない 

2) 非同期例外に関連する振る舞い(System.Thread.Abortを参照)。 

3) グローバリゼーションは提供されないため,文字列の並べ替え順序などの利用者可視機能を含む,

カルチャ情報は各実装において指定する。 

4) スレッドがプリエンプティブに,又は非プリエンプティブにスケジュールすることを前提とするこ

とはできない。この決定は,実装固有である。 

5) アセンブリの検索は,実装固有の機構である。 

6) セキュリティポリシーは,実装固有の機構である。 

7) ファイル名は実装固有である。 

8) 単位は規定されるが,タイマ解決(単位)は実装固有である。 

E.2 

言語及びコンパイラによって制御できる振る舞い 

次に挙げるプログラムの振る舞いは,言語設計,又は言語固有のコンパイラでCILを注意深く生成する

ことによって,制御することができる。CLIは,振る舞いを制御するために必要なあらゆる機能を提供す

るが,省略時で実装固有の最適化を許可する。 

1) 検証不可コードは,任意のメモリにアクセスできるが,可搬であることを保証できない。 

2) 浮動小数点 ‒ コンパイラを使って,すべての中間値を既知の精度に強制的に変換できる。 

3) 整数のオーバフロー ‒ コンパイラを使って,オーバフロー検査を強制的に実行できる。 

4) プラットフォーム固有の整数型を開示する必要はない。また,非透過ハンドルだけのために開示し

たり,利用する前にオーバフロー検査によって,信頼できるよう既知の大きさの値に再キャストし

たりできる。オーバフロー検査を実行しない場合,プラットフォーム固有の整数と固定サイズの整

478 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

数との間の“自由変換”は,可搬性がないことに注意する。 

5) 型の決定論的初期化に可搬性はあるが,“静的変数への最初の参照前”には可搬性がない。言語設計

によって,強制的にすべての初期化を決定論にするか(Javaなど),又は,初期化を決定論的なケ

ースに制限できる(すなわち,単純な静的代入など)。 

E.3 

プログラマが制御できる振る舞い 

次に挙げるプログラムの振る舞いは,プログラマが直接制御することができる。 

1) スレッド安全ではないコードは,単一の実装でも動作が異なる場合がある。特に,64ビットに関連

した原子的実行の保証は遵守する必要があり,64ビット実装でテストするだけでは,こうした問題

をすべて検出することはできない可能性がある。重要なのは,同じ64ビットデータに対して,通常

の読込み/書出し及びインタロックアクセスの両方を用いてはならないことである。 

2) 管理外コードの呼出し,又は,非標準のライブラリ拡張の呼出し。 

3) オブジェクトの終了処理の相対的な順序に依存しない。 

4) データの明示的な配置は使用しない。 

5) 単一のCIL命令内,又は,指定のライブラリメソッド呼出し内で,例外の相対的な順序に依存しな

い。 

479 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

附属書F 

(参考) 

厳密でない違反 

注記 附属書Fは参考情報だけを示す。 

一部のCIL命令では,メモリ及び型の安全性を確保するために暗黙の実行時検査が実行される。本来,

CLIでは,例外の正確さが保証されている。つまり,例外が送出された場合にプログラムの状態が保たれ

る。しかし,暗黙の検査で例外の正確性を強制することによって,重要な最適化が実質的に適用できなく

なる場合がある。プログラマは,特定のメソッドが緩和されていることをカスタム属性を通じて宣言でき

る。“緩和”されているとは,暗黙の実行時検査で発生した例外が正確でなくてもよい,ということを示す。 

緩和された検査では,命令の順序を変更する最適化を許容しつつ,(メモリ及び型の安全性を保つことに

よって)検証可能性が保たれる。特に,次の最適化が使用可能になる。 

− 暗黙の実行時検査をループ外に巻き上げる。 

− ループの繰返しの順序を変更する(ベクトル化,自動マルチスレッド化など)。 

− ループを交換する。 

− インライン展開する。メソッドをインライン展開することによって,少なくとも同等のマクロと同じ

速度になるようにする。 

F.1 

命令の順序変更 

暗黙の実行時検査に依存せず,常に明示的な検査を実行し,明示的に例外を送出するプログラムは,既

存のCLI規格で既に許容されているバリエーション(スレッド間での不揮発性読込み・書出しの非決定性

など)を除けば,緩和によって明らかな影響を受けることはない。さらに,緩和されるのは,暗黙の実行

時検査によって生じる制御の依存関係だけである。それでもなお,データの依存関係は遵守されなければ

ならない。 

厳密なメソッドの作成者は,呼出し側又は呼出し先が緩和されているかどうかについて詳しく知らなく

ても,その振る舞いについて推論することが可能である。これは,厳密な命令がフェンスとして機能する

ためである。一方,ソースレベルで直接インライン展開されたかのように,E緩和メソッドからE緩和メ

ソッドをインライン展開可能な形で呼出したいというニーズがある。そのため,E緩和シーケンスは,複

数のメソッドにまたがることが許容されている。 

F.2 

インライン展開 

インライン展開で,厳密度の異なるメソッドを呼び出す場合には注意が必要である。あるメソッドから,

より緩和されたメソッドを呼び出す場合は,インライン展開が可能である。これは,呼出し先を呼出し側

と同程度に厳密に扱えばよい(呼出し先に与えられている追加的な許容度をすべて無視するなど)。それ以

外の場合(呼出し先の方が,呼出し側よりも厳密度が高い場合),呼出しをインライン展開するためには,

各検査が緩和されているか厳密であるかを注意深く追跡する。又は,呼出し側及びインライン展開された

呼出し先のコピー全体の厳密度を格下げし,呼出し側と呼出し先の厳密度が同程度になるようにする。 

480 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

F.3 

tryブロックに入ったら必ずfinallyハンドラが実行されるという保証 

緩和シーケンスは,保護された重要な領域の境界を超えることができないため,この点は依然として保

証される。このことは,資源の確保及び解放に対する慣例的な用法を維持するために不可欠である。 

例 

bool acquired = false; 

try { 

 acquire(ref acquired); 

 S1; 

} finally { 

 if (acquired) release resource; 

S1でどのようにエラーが発生するかについて理解しているプログラマは少ない。“acquire”,S1及び

“release”が同じ緩和シーケンスの一部として許容される場合,S1でエラーが発生したときに,acquire及

びrelease,又はそのいずれかは,いつでも(他の部分の規則によって)無効にすることができる。この三

つの部分を強制的に三つの別個のシーケンスに分けることによって,S1で発生するエラーの問題を排除す

る。当然,“acquire”のシーケンスで,他の何らかのエラーが起こった場合に生じる問題を排除するもので

はない。しかし,それはCLIレベルでは扱うことのできない問題であり,プログラマに委ねる必要がある。 

緩和シーケンスは,重要でない領域の境界を超えることができる。これは,厳密な例外処理が指定され

ている場合であっても,最適化処理は,こうした領域を削除することが既に許容されているためである。 

F.4 

インターリーブ呼出し 

利用者が注意すべき潜在的危険性は,緩和されたメソッドが,別の緩和されたメソッドを呼び出す場合,

検査が呼出し先から呼出し側(又はその逆)に移行したように見える場合がある点である。したがって,

違反に関係なくプログラムの不変性を維持しなければならないメソッドは,順序変更が発生し,それによ

って不変性が破たん(綻)する場合がある違反に関して,厳密なメソッドとして指定しなければならない。 

例えば,次のメソッドT.Mでは,x+yの不変性が維持される。 

例 

.class M { 

 .field public int32 x; 

 .field public int32 y;  

 .method public void T() cil managed { 

  

.maxstack 2 

  

ldarg.0  

// Compute x=x-1 

  

dup 

  

ldfld x 

  

ldc.i4.1 

  

sub 

  

stfld x 

  

ldarg.0  

// Compute y=y+1 

  

dup 

481 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

  

ldfld y 

  

ldc.i4.1 

  

add 

  

stfld y 

 } 

 ... 

このメソッドが緩和されており,かつ,呼出し側も緩和されている場合,呼出し側は,抑制するデータ

又は制御の依存関係がなければ,その呼出しを,呼出し側の他の命令とインターリーブすることが許可さ

れる。インターリーブされた他の命令のいずれかで違反が生じた場合,Mの副作用がすべて抑制される可

能性がある。したがって,違反によって不変性が失われてしまうことを防ぐ必要がある場合には,メソッ

ドMを厳密として指定しなければならない。 

このような呼出し側からの“干渉”は,わずらわしくなる可能性もあるが,次の2点を容認する緩和さ

れた例外の定義に固有のものと思われる。 

1) 命令の順序変更及び 

2) インライン展開されたメソッド呼出しは,少なくとも直接的なインライン展開と同程度の速さで実

行される。 

F.4.1 

フェンスに関して不採用となった概念 

F.4.1では,“検査フェンス”規則に対する代替案が不採用となった理由について説明する。 

候補としては,揮発性の操作が挙がっていた。これは,既に特定の種類の順序変更が回避されていたた

めである。揮発性メモリ操作を検査フェンスとして扱うことで,重大な部分で干渉が回避される場合があ

る。しかし,これには二つの反対意見が存在する。一つ目は,検査フェンスを必要とするすべての状況が,

揮発性操作と関係があるとは限らないという点である。二つ目は,スレッド間通信を高速に行うために存

在している揮発性参照を損ねる可能性がある,という点である。 

F.5 

例 

F.5.1〜F.5.3では,典型的な最適化手法を示す。また,厳密な例外を適用する場合と比べ,緩和された例

外によって,最適化がいかに容易になったかも併せて参照されたい。 

F.5.1 

検査のループ外への巻上げ 

緩和されたメソッドでは,等差級数的に変化する添字の境界検査をループ外に巻き上げて,極端なケー

スだけを検査対象にすることができる。次に例を示す。 

for( int i=lower; i<upper; ++i ) { 

 a[i] = b[i]; 

 c[i] = d[i]; 

c[i]への代入は,ループ内のすべての境界検査の成功に制御依存するため,厳密なメソッドでは,a及

びbに対する境界検査を巻上げることは困難である。違反によってループが途中で終了した場合,a及び

cの最初の接頭辞が,違反の発生時点までに書き出されなければならない。当然,“二つの版管理”を用い

て巻き上げることもできるが,その場合,生成されるコードの量が倍になる。 

緩和されたメソッドである場合,二つの版管理を使用することなく,境界検査を容易に巻き上げること

482 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

ができる。つまり,コードは,次のように記述されているかのように実行される。 

if(lower < upper) { 

 // “Landing pad” in compiler parlance. 

 if( lower < 0 || upper < a.Length || upper < b.Length || upper < c.Length 

      || upper < d.Length) 

  

throw IndexOutOfRangeException; 

 int i=lower;  

 do { 

  

a[i] = b[i]; // Unchecked 

  

c[i] = d[i]; // Unchecked 

 } while( ++i<upper ); 

このコードでは,NullReferenceExceptionの検査も暗黙的に巻き上げられる点に注目されたい。厳

密な例外を使用した場合,このような巻上げは無効である。これは,a[0]=b[0]に成功した後,cがnull

になることが予想されるためである。同様の理由によって,緩和された例外(具体的には,

CompilationRelaxations.RelaxedArrayExceptions及び

CompilationRelaxations.RelaxedNullReferenceExceptionで緩和するように指定された例外)

を使用すると,両方の代入について,ArrayTypeMismatchExceptionの検査を巻き上げることが可能

となる。緩和によって検査を巻き上げることはできるが,検査を取り除くことはできない点に注目された

い。 

F.5.2 

ループのベクトル化 

通常,ループをベクトル化するには,次の2点が明らかになっている必要がある。 

1) ループの繰返しが互いに非依存である。 

2) ループの繰返しの回数が既知である。 

違反となる可能性のある検査について緩和されたメソッドでは,1点目が偽となることが多い。これは,

違反の可能性が,各ループの繰返しから後続のループの繰返しへと,制御の依存関係を生じさせるためで

ある。緩和されたメソッドでは,こうした制御の依存関係は無視できる。 

ほとんどの場合,緩和されたメソッドでは,検査をループの外に巻き上げることによって,ベクトル化

が単純化される。IA-32 SSE又はPowerPC Altivecなどの“ショートベクトル”SIMDハードウェアでは,

このような巻上げが不可能である場合も,違反によって生じる繰返し間の依存関係の無視が,ベクトル化

に不可欠であることがある。例えば,次のようなループがあるとする。 

for (k = 0; k < n; k++) { 

 x[k] = x[k] + y[k] * s[k].a; 

sは参照の配列である。緩和された文脈でも,null参照の検査をループ外に巻き上げることはできない。

しかし,緩和によって,“アンロール及びジャム”を正常に適用することはできる。このループは,係数4

でアンロールすることによって集約繰返しを作成し,検査をそれぞれの集約繰返しの上巻き上げることが

可能である。 

F.5.3 

ループの自動スレッド化 

次は,SciMark 2.0スイートの疎行列の乗算に対する主要ルーチンをC#で表現したものである。 

483 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

int M = row.Length - 1; 

for (int r=0; r<M; r++) { 

 double sum = 0.0; 

 int rowR = row[r]; 

 int rowRp1 = row[r + 1]; 

 for (int i = rowR; i < rowRp1; i++) 

  

sum += x[ col[i] ] * val[i]; 

 y[r] = sum; 

このルーチンで,外側のループを並列化することは興味深い。厳密なメソッドである場合,そのような

ことは極めて困難である。x[col[i]]が決して違反にならないことが既知であるか,y[r]に対する書出

しを投機的に実行する何らかの手段がなければならない。 

発生する可能性のある違反に関してメソッドが緩和されている場合,一般的なデータの依存関係の問題

だけが解決できれば(つまり,必ずy[r]がx[col[i]]の別名になれば),外側のループを並列化するこ

とができる。ループのいずれかの繰返しで違反が生じた場合,緩和された例外では,他の繰返しを早期に

終了するか,yの状態に関係なく処理を続行することが可能である。 

484 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

附属書G 
(参考) 

並列ライブラリ 

注記 附属書Gでは,参考情報だけを示す。 

附属書Gでは,並列ライブラリを使って記述した完全な例を幾つか示す。 

System.Threading.Parallel内のクラスを使用すると,複数のスレッドのディスパッチ及び同期に

関する詳しい知識がなくても,複数のスレッドを並列実行できるハードウェアの性能を最大限に活かした

並列ループ処理を記述できる。例えば,次のような標準的な順次処理ループがあるとする。 

例 

for( int i=0; i<n; ++i ) { 

    loop body 

これは,並列ループ処理として,次のように書き換えることができる。 

new ParallelFor().Run( delegate( int i ) { 

    loop body 

}); 

G.1 

考察 

プログラマは,ループの繰返しが非依存であり(正確さのため),十分な粒度がある(効率のため)よう

に配慮する必要がある。ループの繰返しが任意の順序で実行可能である,つまり,同時に実行しても正し

い解が得られる場合,ループの繰返しは非依存であるという。粒度とは,ループの繰返しによって実行さ

れる処理量をいう。粒度が小さすぎる場合,想定されている作業に比べて,オーバヘッド(委譲を呼び出

す,他のスレッドとの同期をとるなど)の方が大きくなる可能性がある。粒度を大きくかつ一様にすると

ともに,複数の物理スレッドに対して均等配分するのが困難にならない程度の大きさにするのが理想的で

ある。 

効率の観点からいうと,可能であれば,優先することが望ましいループクラスはParallelForである。

このクラスは,繰返しのためのはん(汎)用的な空間が最も小さいという点で,最も効率的なループクラ

スといえる。 

G.2 

ParallelFor 

ParallelForは,添字が0〜n-1の値をとるループを並列化する場合に使用する。以下は,C#で

ParallelForを使用し,格子上のセルラーオートマトンの繰返し処理を並列化する例である。変数oldState

及びnewStateは,セルの以前の状態及び新しい状態をそれぞれ保持する2次元配列である。 

例 

int n = oldState.GetLength(0); 

new ParallelFor(n-2).Run(delegate(int iteration) { 

    int i = iteration+1; 

     for (int j = 1; j < n-1; j++){ 

485 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

         int count =  

                  (oldState[i-1,j-1] + oldState[i-1,j] + 

oldState[i-1,j+1] + 

                   oldState[  i,j-1] +                   oldState[  i,j+1] 

                   oldState[i+1,j-1] + oldState[i+1,j] + 

oldState[i+1,j+1]); 

              byte s = (count | oldState[i, j]) == 3 ? Live : Dead; 

              newState[i, j] = s; 

     } 

}); 

注意すべき重要な点が二つある。まず,外側のループでは,論理上,iが1〜n-1の範囲で繰り返され

る。しかし,ParallelForクラスによる繰返し処理は,常に0から開始される。したがって,iの理想

的な論理値は,物理的なループの繰返し数iterationから計算される。もう一つは,外側のループは並

列処理されるが,内側のループは順次処理されるという点である。一般に,内側と外側のループでその繰

返しが互いに依存しない場合,外側のループを並列化した方がよい。そうすることによって,最大の粒度

が得られるためである。 

G.3 

ParallelForEach 

通常の列挙子パターンを提供する集団に対して処理を繰り返すようなループは,ParallelForEachを

使って並列化する。次の例では,一連のファイル名を繰返し処理している。 

例 

List<string> files = ...; 

new ParallelForEach(files).Run( delegate(filename) {  

    FileStream f = new FileStream( filename, FileMode.Open ); 

    ...read file f and process it... 

    f.Close(); 

}); 

G.4 

ParallelWhile 

ループ処理の過程で集団が大きくなるような場合は,ParallelWhileを使って並列化する。以下は,

スプレッドシート内のセルを,ParallelWhileを用いて並列的に更新する例である。各セルには,それ

に依存するセルの集合Successors及びゼロに初期化されたフィールドPredecessorCountが存在す

るものと仮定する。それぞれのセルは,その後続セルが更新される前に更新されなければならない。 

例 

void UpdateAll() { 

    // Phase 1: Count predecessors 

    foreach (Cell c in SetOfAllCells) 

        foreach (Cell dependent in currentCell.Sucessors) 

486 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

                   ++dependent.PredecessorCount 

    // Phase 2: Find cells with no predecessors 

    ParallelWhile<Cell> parallelWhile = new ParallelWhile<Cell>(); 

    foreach (Cell c in SetOfAllCells) 

        if (c.PredecessorCount]==0) 

      parallelWhile.Add(c); 

    // Phase 3: Do the updating  

    parallelWhile.Run( delegate(Cell c) { 

        ....update value of cell c... 

       foreach (Cell dependent in c.Sucessors) 

     if (Interlocked.Decrement(ref dependent.PredecessorCount)==0) 

         parallelWhile.Add(dependent); 

    }); 

この例は,典型的なトポロジカルソートとして構成されている。Phase 1及びPhase 2は,順次処理コー

ドである。順次処理されるため,スレッド安全な方法でPredecessorCountを更新する必要はない。Phase 

3は並列処理である。更新準備が完了しているすべてのセル(Phase 2で検出)及び実行準備が完了してい

るセル(Phase 3自体で検出)の処理が開始される。Phase 3は並列処理であるため,PredecessorCount

はスレッド安全な方法で更新される。 

G.5 

デバッグ 

初回デバッグ時には,System.Threading.Parallel.ParallelEnvironment.MaxThreadsを1

に設定する。こうすることで,並列ループ処理クラスで順次実行が可能になる。コードが正常に順次実行

されるのを確認したら,System.Threading.Parallel.ParallelEnvironment.MaxThreadsの値

を大きく設定して試行する。この設定は,アプリケーション領域内のすべての並列ループ処理に影響を及

ぼすため,最終的な実運用コードでは行わない方がよい。 

487 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

索引 

“ゼロ初期化”ビット .............................344, 345 

& 73 

《16進バイト》 ............................................. 112 

《Float32》 ................................................. 115 

《Float64》 ................................................. 115 

《ID》 ............................................................ 113 

《ILファイル》 ............................................. 116 

《Int32》 ..................................................... 112 

《Int64》 ..................................................... 112 

《アセンブリ参照宣言》 ................................. 122 

《アセンブリ宣言》 ........................................ 119 

《値型参照》 .................................................. 163 

《移出属性》 .................................................. 124 

《一重引用符文字列》 .................................... 113 

《引用文字列》............................................... 112 

《解決有効範囲》 ........................................... 126 

《外部ソース宣言》 ........................................ 115 

《型参照》 ..................................................... 126 

《コードラベル》 ........................................... 114 

《識別子》 ..................................................... 113 

《実数》 .................................................. 112, 115 

《宣言》 ......................................................... 116 

《データラベル》 ........................................... 114 

《ドット名》 .................................................. 113 

《バイト列》 .................................................. 115 

《ファイル名》............................................... 115 

《プラットフォーム固有型》 .......................... 128 

《目録資源宣言》 ........................................... 121 

+infinity ........................................................... 76 

4バイト整数 ................................................... 288 

4バイト符号付き整数 ..................................... 288 

8バイト整数 ................................................... 288 

8バイト符号付き整数 ..................................... 288 

abstract ........................................................ 49 

AllowMultiple .............................................. 64 

ArgIterator .................................................. 87 

ArithmeticException ................................. 93 

Attribute ................................................. 63, 72 

AttributeUsageAttribute ................... 63, 64 

BadImageFormatException ......................... 95 

Boolean ......................................................... 290 

byref制約 ......................................................... 33 

castclass ....................................................... 83 

catchハンドラ ................................................ 93 

catchブロック .............................................. 204 

CIL ................................................................... 73 

CLI構成部品 .................................................... 52 

CLIモジュール ................................................. 55 

CLS .......................................................... 56, 213 

CLS拡張側 ....................................................... 13 

CLSフレームワーク ......................................... 12 

Common Type System ...................................... 16 

CTS .................................................................. 16 

DivideByZeroException .............................. 93 

ELEMENT̲TYPE̲BYREF .................................. 292 

ELEMENT̲TYPE̲PTR ...................................... 291 

EntryPointNotFoundException ................. 95 

enum ............................................................... 169 

ERROR ............................................................. 213 

Exception ....................................................... 93 

exception̲continue̲search ................... 337 

exception̲execute̲handler ................... 337 

ExecutionEngineException ....... 93, 287, 310 

expect existing slot ........................................... 48 

F 73, 288 

faultハンドラ ................................................ 93 

faultブロック .............................................. 206 

filterハンドラ .............................................. 93 

final ......................................................... 47, 49 

finallyハンドラ ............................................ 93 

finallyブロック .......................................... 205 

float32 ........................................................... 73 

float64 ........................................................... 73 

getter ............................................................. 50 

488 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

HASTHIS .................................................327, 358 

hide by name ................................................... 47 

hide by name-and-signature............................ 47 

ILAsm構文 ..................................................... 111 

IMAGE̲COR̲ILMETHOD ................................. 302 

IndexOutOfRangeException ....................... 93 

−infinity ......................................................... 76 

Inherit .......................................................... 64 

int16 .............................................................. 73 

int32 ...................................................... 73, 288 

int64 ...................................................... 73, 288 

int8................................................................. 73 

InvalidAddressException ......................... 93 

InvalidCastException ............................... 93 

isinst ............................................................ 83 

MarshalByRefObject ................................. 105 

maxstack ....................................................... 302 

MissingFieldException ....................... 93, 95 

MissingMemberException ........................... 95 

MissingMethodException ..................... 93, 95 

NaN ................................................................. 76 

native int ............................................ 73, 288 

native unsigned int ................................. 73 

new slot............................................................ 48 

NotSupportedException ............................. 95 

null......................................................... 23, 288 

NullReferenceException ........................... 93 

O 73 

op̲Addition .................................................. 61 

op̲AdditionAssignment ............................. 61 

op̲AddressOf ................................................ 60 

op̲Assign ...................................................... 61 

op̲BitwiseAnd .............................................. 61 

op̲BitwiseAndAssignment ......................... 61 

op̲BitwiseOr ................................................ 61 

op̲BitwiseOrAssignment ........................... 61 

op̲Comma ........................................................ 61 

op̲Decrement ................................................ 60 

op̲Division .................................................. 61 

op̲DivisionAssignment ............................. 61 

op̲Equality................................................... 61 

op̲ExclusiveOr ............................................ 61 

op̲ExclusiveOrAssignment ....................... 61 

op̲Explicit............................................. 59, 61 

op̲False ......................................................... 60 

op̲GreaterThan ............................................ 61 

op̲GreaterThanOrEqual .............................. 61 

op̲Implicit............................................. 59, 61 

op̲Increment ................................................ 60 

op̲Inequality .............................................. 61 

op̲LeftShift ................................................ 61 

op̲LeftShiftAssignment............................ 61 

op̲LessThan................................................... 61 

op̲LessThanOrEqual .................................... 61 

op̲LogicalAnd .............................................. 61 

op̲LogicalNot .............................................. 60 

op̲LogicalOr ................................................ 61 

op̲MemberSelection .................................... 61 

op̲Modulus ..................................................... 61 

op̲ModulusAssignment ................................ 61 

op̲MultiplicationAssignment ................. 61 

op̲Multiply................................................... 61 

op̲OnesComplement ...................................... 60 

op̲PointerDereference .............................. 60 

op̲PointerToMemberSelection ................. 61 

op̲RightShift .............................................. 61 

op̲RightShiftAssignment ......................... 61 

op̲SignedRightShift .................................. 61 

op̲Subtraction ............................................ 61 

op̲SubtractionAssignment ....................... 61 

op̲True ........................................................... 60 

op̲UnaryNegation ........................................ 60 

op̲UnaryPlus ................................................ 60 

op̲UnsignedRightShift .............................. 61 

op̲UnsignedRightShiftAssignment ......... 61 

OutOfMemoryException ........................ 93, 287 

OverflowException ...................................... 93 

param type .................................................... 183 

PEファイル .................................................... 216 

RuntimeArgumentHandle ............................ 317 

489 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

RuntimeFieldHandle ................................. 368 

RuntimeMethodHandle ............................... 368 

RuntimeTypeHandle ................................... 368 

RVA .......................................................... 54, 214 

SecurityException ............................... 93, 95 

SecurityPermission.SkipVerification 

 ............................................................305, 345 

serializable ...................................................... 50 

setter ............................................................ 50 

SpecialName .................................................. 60 

StackOverflowException .............. 93, 94, 287 

static ...................................................... 49, 50 

System.ArgIterator ................................. 317 

System.Array ............................... 359, 361, 370 

System.Diagnostics.ConditionalAttrib

ute ............................................................. 210 

System.FlagsAttribute ........................... 211 

System.Math.IEEERemainder ................... 350 

System.ParamArrayAttribute ................. 211 

System.Reflection.DefaultMemberAttri

bute ........................................................... 210 

System.Runtime.CompilerServices.Deci

malConstantAttribute .......................... 210 

System.Runtime.CompilerServices.Faul

tModeAttribute ...................................... 210 

System.Runtime.CompilerServices.Inde

xerNameAttribute .................................. 211 

tail呼出し ..................................................... 88 

this................................................................. 23 

this pointer ...................................................... 23 

ThreadAbortException ............................. 106 

TLS(スレッド局所記憶域) .......................... 210 

tryブロック .................................................. 204 

TypeLoadException ............................... 93, 95 

TypeUnloadedException ............................. 95 

unaligned. .................................................. 105 

unsigned int16 ............................................ 73 

unsigned int32 ............................................ 73 

unsigned int64 ............................................ 73 

unsigned int8 .............................................. 73 

ValidOn ........................................................... 63 

VES .................................................................. 73 

virtual ........................................................... 49 

void ............................................................... 182 

WARNING...................................................... 213 

XMLライブラリ ............................................. 385 

アクセス可能 ..................................................... 27 

アクセス可能権限 .............................................. 27 

アクセス可能性 ................................... 27, 28, 129 

アクセス可能性規則 .......................................... 28 

アクセス可能性属性 ........................................ 194 

アセンブリ ............................... 26, 28, 52, 55, 116 

アセンブリ依存性 .............................................. 55 

アセンブリ言語の表記法 ................................. 287 

アセンブリ有効範囲 .......................................... 26 

値 ................................................................ 16, 18 

値型................................................................... 18 

値型定義............................................................ 45 

値型の継承 ........................................................ 46 

値渡し仮引数 ..................................................... 91 

アプリケーション .............................................. 55 

アプリケーションドメイン .............................. 105 

アプリケーション領域 ..................................... 383 

暗黙的な型 ........................................................ 36 

暗黙的変換 ........................................................ 22 

暗黙の強制型変換 .............................................. 61 

委譲................................................... 38, 174, 201 

イベント.................................................... 43, 200 

イベント契約 ..................................................... 31 

イベント定義 ..................................................... 51 

イベントの継承 ................................................. 47 

イベント表 ...................................................... 224 

入れ子型.......................................................... 157 

入れ子になった型 .............................................. 30 

入れ子になった型定義 ....................................... 52 

インスタンス構成子 ........................................ 182 

インスタンス構築子 ................................ 154, 175 

インスタンス終了化子 ..................................... 154 

インスタンスメソッド ............................... 23, 180 

インタフェース ......................................... 19, 143 

490 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

インタフェース型 ............................................. 18 

インタフェース型定義 ...................................... 39 

インタフェース型の継承 ................................... 46 

インタフェース契約 .................................... 30, 43 

インタフェース定義 .......................................... 39 

隠ぺい ...................................................... 47, 129 

上書き ........................................................ 24, 47 

遠隔処理境界 .................................................. 105 

演算子多重定義................................................. 60 

演算対象の型 .................................................. 297 

演算対象の型の表 ........................................... 287 

エンディアン .................................................. 293 

大文字小文字の違い ........................................ 211 

大文字小文字を区別しない ............................... 58 

大文字小文字を区別する ................................... 58 

大文字小文字を正確に維持する ........................ 58 

オブジェクト .................................................... 19 

オブジェクト型................................................. 18 

オブジェクト型定義 .......................................... 42 

オブジェクト型の継承 ...................................... 45 

オブジェクト構築子 .................................... 44, 71 

オブジェクト参照 ........................................... 290 

オプコード ..................................................... 293 

カーネルプロファイル .................................... 382 

解決例外 ........................................................... 94 

下位バイト先行(little endian)書式 ............. 268 

外部入口点 ....................................................... 56 

拡大 ............................................................ 22, 61 

拡大強制型変換................................................. 61 

拡張数値ライブラリ ........................................ 385 

拡張配列ライブラリ ........................................ 385 

格納域 .............................................................. 22 

格納域識別情報........................................... 31, 32 

格納域制約 ....................................................... 32 

囲む側の型 ....................................................... 30 

可視 .................................................................. 27 

可視性 ................................................. 27, 42, 129 

カスタム ......................................................... 180 

カスタム修飾子............................................... 126 

カスタム属性 ..................................... 63, 126, 207 

仮想............................................................. 24, 49 

仮想実行システム .......................................... 9, 73 

仮想メソッド ....................................... 23, 24, 181 

仮想呼出し ................................................ 24, 179 

仮想呼出し規約 ................................................. 90 

型 ................................................................ 16, 18 

型安全 ......................................................... 10, 35 

型安全な操作 ................................................... 171 

型意味属性 ...................................................... 144 

型規定 ............................................................. 125 

型契約 ............................................................... 30 

型識別情報 ........................................................ 31 

型初期化............................................................ 41 

型初期化子 .............................................. 154, 182 

型付けされた参照仮引数 ................................... 91 

型付けされた参照識別情報 ................................ 33 

型定義 ............................................................... 26 

型定義側............................................................ 36 

型トークン ........................................................ 97 

型の可視性 ........................................................ 27 

型の継承............................................................ 45 

型名................................................................... 26 

型メンバ...................................................... 23, 42 

可搬性 ............................................................. 477 

可変長引数並び ................................................. 87 

可変引数.......................................................... 383 

仮引数識別情報 ........................................... 31, 33 

仮引数対応 ........................................................ 92 

仮引数渡し ........................................................ 90 

管理外ポインタ ................................. 74, 172, 290 

管理外ポインタ型 .............................................. 38 

管理下コード ..................................................... 11 

管理下データ ..................................................... 11 

管理下ポインタ ................................. 75, 172, 290 

擬似カスタム属性 ............................................ 208 

基礎とする型 ................................................... 169 

既存スロットを期待 .......................................... 48 

基底型 ..................................................... 143, 169 

基底クラスライブラリ ..................................... 384 

揮発性書出し ................................................... 107 

491 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

揮発性読込み .................................................. 107 

キャスト ........................................................... 23 

境界調整 ......................................................... 105 

強制型変換 ....................................................... 22 

共通型システム............................................. 9, 16 

共通言語規定 .................................................... 56 

共通言語仕様 ...................................................... 9 

共通中間言語 ...................................................... 2 

許可クラス ..................................................... 207 

局所識別情報 .................................................... 33 

局所変数 ........................................................... 87 

局所変数識別情報 ............................................. 33 

局所変数配列 .................................................... 85 

局所予備メモリ領域 .................................... 85, 87 

具象性 .............................................................. 42 

組換え .....................................................192, 195 

組換え情報 ..................................................... 182 

組込み型 ........................................................... 18 

組込み参照型 .................................................... 18 

組込みの原子的書出し .................................... 107 

組込みの原子的読込み .................................... 107 

クラス .............................................................. 19 

クラス型 ........................................................... 40 

クラス型定義 .................................................... 40 

クラス契約 ................................................. 30, 43 

クラス構築子 .............................................. 44, 71 

クラス定義 ....................................................... 40 

クラスの配置 .................................................... 54 

計算機状態 ....................................................... 83 

計算された呼出し先 .......................................... 90 

継承 .................................................................. 45 

継承要求 ........................................................... 29 

契約 .................................................................. 30 

結合文字 ........................................................... 58 

厳密な型 ........................................................... 19 

公開 .................................................................. 28 

構成部品 ........................................................... 52 

構成部品メタデータ .......................................... 52 

構築子 .............................................................. 43 

コールバック .................................................. 179 

互換......................................................... 171, 173 

ごみ集め............................................................ 79 

コンパイラ制御 ................................................. 28 

最終............................................................. 47, 49 

最適化 ............................................................. 106 

参照................................................................... 56 

参照型 ............................................................... 18 

参照される実体 ................................................. 27 

参照元 ............................................................... 27 

参照要求............................................................ 29 

参照渡し仮引数 ................................................. 91 

識別子 ....................................................... 58, 113 

識別情報....................... 30, 31, 124, 173, 180, 199 

識別情報項目 ................................................... 126 

次元数 ............................................................. 167 

自己記述的 ........................................................ 52 

自己反映.......................................................... 383 

自己反映ライブラリ ........................................ 385 

実行エンジン ................................................... 287 

実行時基盤ライブラリ ..................................... 384 

実行時ハンドル ............................................... 368 

実装属性.......................................................... 182 

実引数 ............................................................... 87 

実引数配列 .................................................. 85, 87 

私的................................................................... 28 

自動配置............................................................ 54 

集約データ ........................................................ 80 

終了化子............................................................ 44 

主キー ............................................................. 212 

縮小............................................................. 22, 61 

縮小強制型変換 ................................................. 61 

順次配置............................................................ 54 

条件分岐............................................................ 88 

省略記号.......................................................... 182 

初期化値不変制約 .............................................. 32 

初期化フラグ ........................................... 344, 346 

指令................................................................. 118 

新規スロット ..................................................... 48 

真性カスタム属性 ............................................ 208 

数値データ型 ................................................... 288 

492 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

スクリプトコンパイラ .................................... 213 

スタック推移 .................................................. 297 

スタック遷移図............................................... 287 

スレッド ..................................................107, 178 

静的 ............................................................ 49, 50 

静的フィールド................................................. 24 

静的メソッド ....................................... 23, 24, 180 

正当性検証 ............................................2, 35, 109 

正当性検証可能............................................... 110 

正当性検証可能性 ....................................287, 303 

正当性検証不能コード .................................... 110 

正の無限大 ....................................................... 76 

セキュリティ .................................................... 27 

セキュリティ記述子 .......................................... 85 

セキュリティ許可 ............................................. 29 

セキュリティ宣言 ........................................... 206 

セキュリティ属性 ........................................... 209 

セキュリティ動作 ........................................... 221 

セキュリティ要求 ............................................. 29 

接頭辞 ............................................................ 310 

ゼロ初期化ビット ........................................... 305 

相互運用属性 .................................................. 233 

添字指定された特性 .......................................... 63 

総称インスタンス ........................................... 133 

総称メソッド定義 ........................................... 133 

相対仮想アドレス ............................................. 54 

大域的状態 ....................................................... 83 

大域的に静的 .................................................... 57 

大域的有効範囲............................................... 192 

大域的レベル .................................................. 179 

代入互換 ........................................................... 22 

代入互換性 ....................................................... 34 

代入互換な格納域 ............................................. 22 

代理 ................................................................ 105 

多重定義 ........................................................... 58 

妥当性確認 ..................................................... 212 

妥当性検証 ..................................................... 109 

妥当な名前 ....................................................... 24 

単項演算子 ....................................................... 60 

単純 ................................................................ 211 

短整数 ............................................................. 288 

仲介コード .............................................. 342, 368 

抽象............................................................. 42, 49 

抽象オブジェクト型 .......................................... 42 

抽象仮想メソッド ............................................ 181 

抽象クラス ........................................................ 42 

抽象クラス型 ..................................................... 40 

抽象メソッド ..................................................... 42 

直列化可能 ........................................................ 50 

ディスパッチ ................................................... 178 

適合性 .................................................................2 

同一性 ............................................................... 21 

同一性演算子 ..................................................... 21 

等価演算子 .................................................. 21, 22 

等価性 ......................................................... 21, 22 

同期化されたメソッド ..................................... 107 

同期呼出し ...................................................... 177 

同値演算子 ........................................................ 21 

特性........................................................... 42, 199 

特性契約............................................................ 30 

特性定義............................................................ 50 

特性の継承 ........................................................ 47 

内容目録............................................................ 55 

名前................................................................... 24 

名前及び識別情報による隠ぺい ......................... 47 

名前空間.......................................................... 117 

名前付け............................................................ 24 

名前による隠ぺい .............................................. 47 

2項演算子 ......................................................... 60 

任意選択修飾子 ................................................. 57 

ネットワークライブラリ ................................. 384 

配置................................................................... 47 

配置属性.......................................................... 144 

バイト順序 ...................................................... 106 

バイナリ形式 ................................................... 287 

配列................................................................. 167 

配列型 ......................................................... 23, 36 

配列要素............................................................ 23 

ハンドラ区域 ..................................................... 97 

ハンドラブロック ............................................ 204 

493 

X 3016:2010 (ISO/IEC 23271:2006) 

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

ハンドル ......................................................... 189 

ヒープ ............................................................ 211 

非公開型 ........................................................... 58 

非公開メンバ .................................................... 58 

非数 .................................................................. 76 

非静的(インスタンス)フィールド ................. 24 

必す(須)修飾子 ............................................. 57 

ビットマスク .................................................. 211 

非透過クラス .................................................... 83 

非同期呼出し .................................................. 178 

非ベクトル配列............................................... 383 

表 ................................................................... 211 

評価スタック ....................................... 85, 86, 297 

標準公開鍵 ..................................................... 119 

標準プロファイル ........................................... 381 

標準ライブラリ............................................... 384 

ファミリ ........................................................... 28 

ファミリ及びアセンブリ ................................... 28 

ファミリ又はアセンブリ ................................... 28 

フィールド .......................................... 23, 42, 193 

フィールド契約属性 ........................................ 194 

フィールド定義................................................. 50 

フィールドの継承 ............................................. 47 

フィルタブロック ........................................... 205 

フィルタ領域 .................................................... 97 

封印型 .............................................................. 46 

封印された ....................................................... 46 

封印宣言 ......................................................... 174 

複合型 .............................................................. 23 

符号化 ............................................................ 211 

浮動小数点 ..................................................... 382 

浮動小数点数 .................................................. 289 

負の無限大 ....................................................... 76 

フラグ ............................................................ 211 

プラットフォーム ........................................... 212 

プラットフォーム固有の大きさの整数 ............ 288 

プラットフォーム固有の大きさの浮動小数点数 

 ................................................................... 288 

フレーム拡張 .................................................. 383 

プログラム言語C# ............................................. 3 

プロファイル ........................................... 288, 379 

ベクトル.......................................................... 166 

変異形 ............................................................. 292 

変換演算子 ........................................................ 61 

返却状態ハンドル .............................................. 85 

返却値の型 ...................................................... 182 

ポインタ.......................................................... 290 

ポインタ型 .......................................... 18, 38, 171 

防護ブロック ................................................... 204 

ホーム ............................................................... 80 

保護されている ............................................... 203 

保護ブロック ............................................. 97, 204 

ボックス化 .......................................... 20, 82, 199 

ボックス化値 ..................................................... 20 

ボックス化解除 ........................................... 20, 82 

ボックス化型 ..................................................... 20 

ボックス化された値型 ....................................... 46 

無条件分岐 ........................................................ 88 

明示的クラス定義 .............................................. 40 

明示的な型 ........................................................ 36 

明示的な強制型変換 .......................................... 61 

明示的な原子的操作 ........................................ 107 

明示的なロック及びモニタ .............................. 107 

明示的変換 ........................................................ 22 

明示配置............................................................ 54 

命名パターン ..................................................... 62 

命令ストリーム ............................................... 301 

命令の接頭辞 ................................................... 310 

命令変異形 ...................................................... 292 

命令変異形の表 ............................................... 292 

命令ポインタ ..................................................... 85 

メソッド...................................................... 23, 42 

メソッド契約 ..................................................... 30 

メソッド識別情報 ........................................ 31, 33 

メソッド実装メタデータ ................................... 54 

メソッド状態 ..................................................... 85 

メソッド情報ハンドル ....................................... 85 

メソッド属性 ................................................... 182 

メソッド定義 ..................................................... 49 

メソッド飛越し ................................................. 88 

494 

X 3016:2010 (ISO/IEC 23271:2006) 

  

2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。 

メソッドの継承................................................. 47 

メソッドの先頭............................................... 182 

メソッドポインタ ........................................... 173 

メソッド呼出し................................................. 88 

メタデータ .................................... 9, 52, 109, 180 

メタデータオブジェクト ................................... 53 

メタデータトークン ........................... 53, 222, 310 

メタデータの拡張性 .......................................... 56 

メタデータへのアクセス ................................... 53 

メタデータ論理形式 ........................................ 211 

メンバ .............................................................. 23 

メンバ定義 ....................................................... 49 

メンバの継承 .................................................... 46 

メンバ有効範囲................................................. 26 

目録 ................................................................ 118 

目録資源 ......................................................... 121 

モジュール ..................................................... 116 

モジュール情報................................................. 83 

文字列の強制収容(string interning) .......... 367 

有効範囲 .............................................. 25, 42, 204 

有効範囲付け .................................................... 25 

呼出し規約 ..............................................181, 182 

呼出し情報 ....................................................... 31 

呼出し命令 ....................................................... 89 

呼出し元記述子................................................. 89 

ライブラリ ..................................................... 379 

ラベル ............................................................ 114 

リテラル制約 .................................................... 32 

リテラル値 ..................................................... 211 

リトルエンディアン ........................................ 293 

リモーティング............................................... 383 

利用者文字列ヒープ中 .................................... 310 

例外 .................................................................. 63 

例外処理 ..................................................... 88, 93 

例外のタイミング ............................................. 95 

列挙型 ............................................................ 169 

ロック ............................................................ 107