モニタリング C API
******************

バージョン 3.13 で追加。

拡張モジュールがイベントモニタリングシステムと連携する必要がある場合が
あります。 イベントの購読やコールバックの登録は、"sys.monitoring" が公
開する Python API で行えます。


実行イベントの発生
******************

以下の関数を使うと、拡張モジュールが Python コードの実行をエミュレート
するときにモニタリングイベントを発生させられます。 各関数は、イベント
の有効化状態を簡潔に保持する "PyMonitoringState" 構造体と、イベントの
引数を受け取ります。 イベントの引数には、コードオブジェクトを表す
"PyObject*"、命令オフセット、場合によってはイベント固有の追加引数が含
まれます (各イベントのコールバックのシグネチャは "sys.monitoring" を参
照してください)。 "codelike" 引数には、"types.CodeType" またはそれをエ
ミュレートする型のインスタンスを指定してください。

VM はイベントを発生させるときにトレースを無効にするため、利用者のコー
ドで無効にする必要はありません。

以下で現在の例外を扱うと記載された関数を除き、例外が設定された状態でモ
ニタリング関数を呼び出してはいけません。

type PyMonitoringState

   イベント種別の状態を表します。 利用者が領域を割り当て、内容は以下の
   モニタリング API 関数が管理します。

以下の関数はすべて、成功した場合は 0 を返し、エラーの場合は例外を設定
して -1 を返します。

イベントの説明は "sys.monitoring" を参照してください。

int PyMonitoring_FirePyStartEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset)

   "PY_START" イベントを発生させます。

int PyMonitoring_FirePyResumeEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset)

   "PY_RESUME" イベントを発生させます。

int PyMonitoring_FirePyReturnEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset, PyObject *retval)

   "PY_RETURN" イベントを発生させます。

int PyMonitoring_FirePyYieldEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset, PyObject *retval)

   "PY_YIELD" イベントを発生させます。

int PyMonitoring_FireCallEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset, PyObject *callable, PyObject *arg0)

   "CALL" イベントを発生させます。

int PyMonitoring_FireLineEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset, int lineno)

   "LINE" イベントを発生させます。

int PyMonitoring_FireJumpEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset, PyObject *target_offset)

   "JUMP" イベントを発生させます。

int PyMonitoring_FireBranchLeftEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset, PyObject *target_offset)

   "BRANCH_LEFT" イベントを発生させます。

int PyMonitoring_FireBranchRightEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset, PyObject *target_offset)

   "BRANCH_RIGHT" イベントを発生させます。

int PyMonitoring_FireCReturnEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset, PyObject *retval)

   "C_RETURN" イベントを発生させます。

int PyMonitoring_FirePyThrowEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset)

   現在の例外 ("PyErr_GetRaisedException()" が返すもの) を使って
   "PY_THROW" イベントを発生させます。

int PyMonitoring_FireRaiseEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset)

   現在の例外 ("PyErr_GetRaisedException()" が返すもの) を使って
   "RAISE" イベントを発生させます。

int PyMonitoring_FireCRaiseEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset)

   現在の例外 ("PyErr_GetRaisedException()" が返すもの) を使って
   "C_RAISE" イベントを発生させます。

int PyMonitoring_FireReraiseEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset)

   現在の例外 ("PyErr_GetRaisedException()" が返すもの) を使って
   "RERAISE" イベントを発生させます。

int PyMonitoring_FireExceptionHandledEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset)

   現在の例外 ("PyErr_GetRaisedException()" が返すもの) を使って
   "EXCEPTION_HANDLED" イベントを発生させます。

int PyMonitoring_FirePyUnwindEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset)

   現在の例外 ("PyErr_GetRaisedException()" が返すもの) を使って
   "PY_UNWIND" イベントを発生させます。

int PyMonitoring_FireStopIterationEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset, PyObject *value)

   "STOP_ITERATION" イベントを発生させます。 "value" が
   "StopIteration" のインスタンスなら、それを使います。 それ以外の場合
   は、"value" を引数として新しい "StopIteration" インスタンスを作成し
   ます。


モニタリング状態の管理
======================

モニタリング状態は、モニタリングスコープを使って管理できます。 通常、
一つのスコープが一つの Python 関数に対応します。

int PyMonitoring_EnterScope(PyMonitoringState *state_array, uint64_t *version, const uint8_t *event_types, Py_ssize_t length)

   モニタリング対象のスコープに入ります。 "event_types" は、そのスコー
   プから発生し得るイベントの ID の配列です。 例えば "PY_START" イベン
   トの ID は "PY_MONITORING_EVENT_PY_START" で、この値は
   "sys.monitoring.events.PY_START" の 2 を底とする対数に等しくなりま
   す。 "state_array" は、"event_types" 内の各イベントに対応するモニタ
   リング状態の配列です。 領域は利用者が割り当て、イベントの有効化状態
   は "PyMonitoring_EnterScope()" が設定します。 "event_types" (したが
   って "state_array" も) のサイズは "length" で指定します。

   "version" 引数は、利用者が "state_array" と一緒に領域を割り当て、0
   に初期化しておく値へのポインタです。 その後は
   "PyMonitoring_EnterScope()" 自身だけが値を設定するようにしてくださ
   い。 この値によって、前回の呼び出し以降にイベントの状態が変化したか
   どうかを判断し、変化していなければ速やかに戻ることができます。

   ここでいうスコープは、関数、クラス、メソッドといった字句スコープで
   す。 字句スコープに入るたびに "PyMonitoring_EnterScope()" を呼び出
   してください。 再帰的な Python 関数をエミュレートする場合などは、同
   じ "state_array" と "version" を再利用してスコープに再び入れます。
   ジェネレータをエミュレートする場合など、コードに相当するオブジェク
   トの実行を一時停止するときは、スコープを一度出てから再び入る必要が
   あります。

   "event_types" に使うマクロは次のとおりです。

   +----------------------------------------------------+---------------------------------------+
   | マクロ                                             | イベント                              |
   |====================================================|=======================================|
   | PY_MONITORING_EVENT_BRANCH_LEFT                    | "BRANCH_LEFT"                         |
   +----------------------------------------------------+---------------------------------------+
   | PY_MONITORING_EVENT_BRANCH_RIGHT                   | "BRANCH_RIGHT"                        |
   +----------------------------------------------------+---------------------------------------+
   | PY_MONITORING_EVENT_CALL                           | "CALL"                                |
   +----------------------------------------------------+---------------------------------------+
   | PY_MONITORING_EVENT_C_RAISE                        | "C_RAISE"                             |
   +----------------------------------------------------+---------------------------------------+
   | PY_MONITORING_EVENT_C_RETURN                       | "C_RETURN"                            |
   +----------------------------------------------------+---------------------------------------+
   | PY_MONITORING_EVENT_EXCEPTION_HANDLED              | "EXCEPTION_HANDLED"                   |
   +----------------------------------------------------+---------------------------------------+
   | PY_MONITORING_EVENT_INSTRUCTION                    | "INSTRUCTION"                         |
   +----------------------------------------------------+---------------------------------------+
   | PY_MONITORING_EVENT_JUMP                           | "JUMP"                                |
   +----------------------------------------------------+---------------------------------------+
   | PY_MONITORING_EVENT_LINE                           | "LINE"                                |
   +----------------------------------------------------+---------------------------------------+
   | PY_MONITORING_EVENT_PY_RESUME                      | "PY_RESUME"                           |
   +----------------------------------------------------+---------------------------------------+
   | PY_MONITORING_EVENT_PY_RETURN                      | "PY_RETURN"                           |
   +----------------------------------------------------+---------------------------------------+
   | PY_MONITORING_EVENT_PY_START                       | "PY_START"                            |
   +----------------------------------------------------+---------------------------------------+
   | PY_MONITORING_EVENT_PY_THROW                       | "PY_THROW"                            |
   +----------------------------------------------------+---------------------------------------+
   | PY_MONITORING_EVENT_PY_UNWIND                      | "PY_UNWIND"                           |
   +----------------------------------------------------+---------------------------------------+
   | PY_MONITORING_EVENT_PY_YIELD                       | "PY_YIELD"                            |
   +----------------------------------------------------+---------------------------------------+
   | PY_MONITORING_EVENT_RAISE                          | "RAISE"                               |
   +----------------------------------------------------+---------------------------------------+
   | PY_MONITORING_EVENT_RERAISE                        | "RERAISE"                             |
   +----------------------------------------------------+---------------------------------------+
   | PY_MONITORING_EVENT_STOP_ITERATION                 | "STOP_ITERATION"                      |
   +----------------------------------------------------+---------------------------------------+
   | PY_MONITORING_EVENT_BRANCH  バージョン 3.14 で非推 | "BRANCH_LEFT" と "BRANCH_RIGHT"       |
   | 奨: 代わりに "PY_MONITORING_EVENT_BRANCH_LEFT" と  |                                       |
   | "PY_MONITORING_EVENT_BRANCH_RIGHT" を使ってくださ  |                                       |
   | い。                                               |                                       |
   +----------------------------------------------------+---------------------------------------+

int PyMonitoring_ExitScope(void)

   "PyMonitoring_EnterScope()" で最後に入ったスコープを出ます。

int PY_MONITORING_IS_INSTRUMENTED_EVENT(uint8_t ev)

   イベント ID "ev" に対応するイベントが ローカルイベント の場合に真を
   返します。

   Added in version 3.13.

   バージョン 3.14 で ソフト非推奨 <Soft deprecated>.
