API C de Monitoramento
**********************

Adicionada na versão 3.13.

Uma extensão pode precisar interagir com o sistema de monitoramento de
eventos. É possível registrar funções de retorno e se inscrever para
receber eventos através da API Python exposta em "sys.monitoring".


Gerando Eventos de Execução
***************************

As funções abaixo permitem que extensões dispararem eventos de
monitoramento emulando a execução de código Python. Cada uma dessas
funções recebe uma estrutura "PyMonitoringState" que contém informação
concisa sobre o estado de ativação de eventos, bem como os argumentos
dos eventos, que incluem um "PyObject*" representando o objeto de
código, a posição da instrução no bytecode, e, em alguns casos,
argumentos adicionais específicos para o evento (veja "sys.monitoring"
para detalhes sobre as assinaturas das funções de retorno de
diferentes eventos). O argumento "codelike" deve ser uma instância da
classe "types.CodeType" ou de um tipo que a emule.

A VM desabilita o rastreamento quando dispara um evento, de forma que
não há necessidade do código do usuário fazer isso.

Funções de monitoramento não devem ser chamadas com uma exceção
definida, exceto as marcadas abaixo como funções que trabalham com a
exceção atual.

type PyMonitoringState

   Representação do estado de um tipo de evento. Alocada pelo usuário,
   enquanto o seu conteúdo é mantido pelas funções da API de
   monitoramento descritas abaixo.

Todas as funções abaixo retornam 0 para indicar sucesso e -1 (com uma
exceção definida) para indicar erro.

Veja "sys.monitoring" para descrições dos eventos.

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

   Dispara um evento "PY_START".

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

   Dispara um evento "PY_RESUME".

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

   Dispara um evento "PY_RETURN".

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

   Dispara um evento "PY_YIELD".

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

   Dispara um evento "CALL".

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

   Dispara um evento "LINE".

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

   Dispara um evento "JUMP".

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

   Dispara um evento "BRANCH".

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

   Dispara um evento "C_RETURN".

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

   Dispara um evento "PY_THROW" com a exceção atual (conforme
   retornada por "PyErr_GetRaisedException()").

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

   Dispara um evento "RAISE" com a exceção atual (conforme retornada
   por "PyErr_GetRaisedException()").

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

   Dispara um evento "C_RAISE" com a exceção atual (conforme retornada
   por "PyErr_GetRaisedException()").

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

   Dispara um evento "RERAISE" com a exceção atual (conforme retornada
   por "PyErr_GetRaisedException()").

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

   Dispara um evento "EXCEPTION_HANDLED" com a exceção atual (conforme
   retornada por "PyErr_GetRaisedException()").

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

   Dispara um evento "PY_UNWIND" com a exceção atual (conforme
   retornada por "PyErr_GetRaisedException()").

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

   Dispara um evento "STOP_ITERATION". Se "value" for uma instância de
   "StopIteration", ele é usado. Caso contrário, uma nova instância de
   "StopIteration" é criada com "value" como o argumento.


Gerenciando o Estado de um Monitoramento
========================================

Estados de monitoramento podem ser gerenciados com a ajuda de escopos
de monitoramento. Um escopo corresponderia tipicamente a um função
python.

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

   Enter a monitored scope. "event_types" is an array of the event IDs
   for events that may be fired from the scope. For example, the ID of
   a "PY_START" event is the value "PY_MONITORING_EVENT_PY_START",
   which is numerically equal to the base-2 logarithm of
   "sys.monitoring.events.PY_START". "state_array" is an array with a
   monitoring state entry for each event in "event_types", it is
   allocated by the user but populated by "PyMonitoring_EnterScope()"
   with information about the activation state of the event. The size
   of "event_types" (and hence also of "state_array") is given in
   "length".

   The "version" argument is a pointer to a value which should be
   allocated by the user together with "state_array" and initialized
   to 0, and then set only by "PyMonitoring_EnterScope()" itself. It
   allows this function to determine whether event states have changed
   since the previous call, and to return quickly if they have not.

   The scopes referred to here are lexical scopes: a function, class
   or method. "PyMonitoring_EnterScope()" should be called whenever
   the lexical scope is entered. Scopes can be reentered, reusing the
   same *state_array* and *version*, in situations like when emulating
   a recursive Python function. When a code-like's execution is
   paused, such as when emulating a generator, the scope needs to be
   exited and re-entered.

   The macros for *event_types* are:

   +----------------------------------------------------+---------------------------------------+
   | Macro                                              | Evento                                |
   |====================================================|=======================================|
   | PY_MONITORING_EVENT_BRANCH                         | "BRANCH"                              |
   +----------------------------------------------------+---------------------------------------+
   | 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"                      |
   +----------------------------------------------------+---------------------------------------+

int PyMonitoring_ExitScope(void)

   Exit the last scope that was entered with
   "PyMonitoring_EnterScope()".
