Skip to content

teach dis how to interpret the oparg of ENTER_EXECUTOR  #112383

Closed

Description

@iritkatriel

Activity

  1. gvanrossum commented on Nov 24, 2023

    @gvanrossum
    Member

    Hm... I think it's not that simple. The oparg of ENTER_EXECUTOR is unrelated to the oparg of the JUMP_BACKWARD it overwrites. It is an index in the table of executors associated (optionally) with the code object. The executor saves the origin opcode (currently always JUMP_BACKWARD, but that may change) and oparg (low byte only) in its vmdata field. Note that if there are EXTENDED_ARG prefixes those are unchanged and unaffected -- the executor index must fit in one byte and only the low byte of the full oparg is saved.

    I expect that in order to handle ENTER_EXECUTOR correctly in dis and other things that inspect the "adaptive" (read: specialized) bytecode, we need an API on the code object to retrieve the executors, or at least the original vmdata for the executors.

  2. changed the title [-]Make the oparg of ENTER_EXECUTOR mean the same as that of JUMP_BACKWARD[/-] [+]teach dis how to interpret the oparg of ENTER_EXECUTOR [/+] on Nov 28, 2023
  3. added
    stdlibStandard Library Python modules in the Lib/ directory
    on Dec 1, 2023
  4. added a commit that references this issue on Dec 15, 2023
  5. added a commit that references this issue on Feb 11, 2024
  6. hugovk commented on Mar 15, 2024

    @hugovk
    Member

    Triage: can this be closed or is there more to do?

  7. iritkatriel commented on Mar 15, 2024

    @iritkatriel
    MemberAuthor

    I don't think we know what to do here.

  8. gvanrossum commented on Mar 15, 2024

    @gvanrossum
    Member

    If you can import _testinternalcapi, you can get a hold of the executor (ex = _testinternalcapi.get_executor(co, offset)) and the executor object now has methods get_opcode() and get_oparg() that return those fields (only the lower byte of oparg).

    >>> def f():
    ...     for i in range(20):
    ...         i += 1
    ...     return i
    ... 
    >>> f()
    20
    >>> f()
    20
    >>> f()
    20
    >>> c = f.__code__
    >>> import dis
    >>> import _testinternalcapi as t
    >>> dis.dis(c, adaptive=1, show_offsets=1)
      1          0       RESUME_CHECK             0
    
      2          2       LOAD_GLOBAL_BUILTIN      1 (range + NULL)
                12       LOAD_CONST               1 (20)
                14       CALL_BUILTIN_CLASS       1
                22       GET_ITER
          L1:   24       FOR_ITER_RANGE           8 (to L2)
                28       STORE_FAST               0 (i)
    
      3         30       LOAD_FAST                0 (i)
                32       LOAD_CONST               2 (1)
                34       BINARY_OP_ADD_INT       13 (+=)
                38       STORE_FAST               0 (i)
                40       ENTER_EXECUTOR          10
    
      2   L2:   44       END_FOR
                46       POP_TOP
    
      4         48       LOAD_FAST_CHECK          0 (i)
                50       RETURN_VALUE
    >>> e = t.get_executor(c, 40)
    >>> e
    <uop_executor object at 0x1037a3b40>
    >>> e.get_oparg()
    10
    >>> e.get_opcode()
    77
    >>> 
    
  9. self-assigned this
    on Mar 22, 2024
  10. added a commit that references this issue on Mar 23, 2024
  11. added a commit that references this issue on Mar 23, 2024
  12. added a commit that references this issue on Mar 25, 2024
  13. added a commit that references this issue on Apr 17, 2024
  14. added a commit that references this issue on Sep 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

stdlibStandard Library Python modules in the Lib/ directory

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions