context.py 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. """Helpers that store information about functions and the related classes."""
  2. from __future__ import annotations
  3. from mypy.nodes import FuncItem
  4. from mypyc.ir.class_ir import ClassIR
  5. from mypyc.ir.func_ir import INVALID_FUNC_DEF
  6. from mypyc.ir.ops import BasicBlock, Value
  7. from mypyc.irbuild.targets import AssignmentTarget
  8. class FuncInfo:
  9. """Contains information about functions as they are generated."""
  10. def __init__(
  11. self,
  12. fitem: FuncItem = INVALID_FUNC_DEF,
  13. name: str = "",
  14. class_name: str | None = None,
  15. namespace: str = "",
  16. is_nested: bool = False,
  17. contains_nested: bool = False,
  18. is_decorated: bool = False,
  19. in_non_ext: bool = False,
  20. ) -> None:
  21. self.fitem = fitem
  22. self.name = name
  23. self.class_name = class_name
  24. self.ns = namespace
  25. # Callable classes implement the '__call__' method, and are used to represent functions
  26. # that are nested inside of other functions.
  27. self._callable_class: ImplicitClass | None = None
  28. # Environment classes are ClassIR instances that contain attributes representing the
  29. # variables in the environment of the function they correspond to. Environment classes are
  30. # generated for functions that contain nested functions.
  31. self._env_class: ClassIR | None = None
  32. # Generator classes implement the '__next__' method, and are used to represent generators
  33. # returned by generator functions.
  34. self._generator_class: GeneratorClass | None = None
  35. # Environment class registers are the local registers associated with instances of an
  36. # environment class, used for getting and setting attributes. curr_env_reg is the register
  37. # associated with the current environment.
  38. self._curr_env_reg: Value | None = None
  39. # These are flags denoting whether a given function is nested, contains a nested function,
  40. # is decorated, or is within a non-extension class.
  41. self.is_nested = is_nested
  42. self.contains_nested = contains_nested
  43. self.is_decorated = is_decorated
  44. self.in_non_ext = in_non_ext
  45. # TODO: add field for ret_type: RType = none_rprimitive
  46. def namespaced_name(self) -> str:
  47. return "_".join(x for x in [self.name, self.class_name, self.ns] if x)
  48. @property
  49. def is_generator(self) -> bool:
  50. return self.fitem.is_generator or self.fitem.is_coroutine
  51. @property
  52. def is_coroutine(self) -> bool:
  53. return self.fitem.is_coroutine
  54. @property
  55. def callable_class(self) -> ImplicitClass:
  56. assert self._callable_class is not None
  57. return self._callable_class
  58. @callable_class.setter
  59. def callable_class(self, cls: ImplicitClass) -> None:
  60. self._callable_class = cls
  61. @property
  62. def env_class(self) -> ClassIR:
  63. assert self._env_class is not None
  64. return self._env_class
  65. @env_class.setter
  66. def env_class(self, ir: ClassIR) -> None:
  67. self._env_class = ir
  68. @property
  69. def generator_class(self) -> GeneratorClass:
  70. assert self._generator_class is not None
  71. return self._generator_class
  72. @generator_class.setter
  73. def generator_class(self, cls: GeneratorClass) -> None:
  74. self._generator_class = cls
  75. @property
  76. def curr_env_reg(self) -> Value:
  77. assert self._curr_env_reg is not None
  78. return self._curr_env_reg
  79. class ImplicitClass:
  80. """Contains information regarding implicitly generated classes.
  81. Implicit classes are generated for nested functions and generator
  82. functions. They are not explicitly defined in the source code.
  83. NOTE: This is both a concrete class and used as a base class.
  84. """
  85. def __init__(self, ir: ClassIR) -> None:
  86. # The ClassIR instance associated with this class.
  87. self.ir = ir
  88. # The register associated with the 'self' instance for this generator class.
  89. self._self_reg: Value | None = None
  90. # Environment class registers are the local registers associated with instances of an
  91. # environment class, used for getting and setting attributes. curr_env_reg is the register
  92. # associated with the current environment. prev_env_reg is the self.__mypyc_env__ field
  93. # associated with the previous environment.
  94. self._curr_env_reg: Value | None = None
  95. self._prev_env_reg: Value | None = None
  96. @property
  97. def self_reg(self) -> Value:
  98. assert self._self_reg is not None
  99. return self._self_reg
  100. @self_reg.setter
  101. def self_reg(self, reg: Value) -> None:
  102. self._self_reg = reg
  103. @property
  104. def curr_env_reg(self) -> Value:
  105. assert self._curr_env_reg is not None
  106. return self._curr_env_reg
  107. @curr_env_reg.setter
  108. def curr_env_reg(self, reg: Value) -> None:
  109. self._curr_env_reg = reg
  110. @property
  111. def prev_env_reg(self) -> Value:
  112. assert self._prev_env_reg is not None
  113. return self._prev_env_reg
  114. @prev_env_reg.setter
  115. def prev_env_reg(self, reg: Value) -> None:
  116. self._prev_env_reg = reg
  117. class GeneratorClass(ImplicitClass):
  118. """Contains information about implicit generator function classes."""
  119. def __init__(self, ir: ClassIR) -> None:
  120. super().__init__(ir)
  121. # This register holds the label number that the '__next__' function should go to the next
  122. # time it is called.
  123. self._next_label_reg: Value | None = None
  124. self._next_label_target: AssignmentTarget | None = None
  125. # These registers hold the error values for the generator object for the case that the
  126. # 'throw' function is called.
  127. self.exc_regs: tuple[Value, Value, Value] | None = None
  128. # Holds the arg passed to send
  129. self.send_arg_reg: Value | None = None
  130. # The switch block is used to decide which instruction to go using the value held in the
  131. # next-label register.
  132. self.switch_block = BasicBlock()
  133. self.continuation_blocks: list[BasicBlock] = []
  134. @property
  135. def next_label_reg(self) -> Value:
  136. assert self._next_label_reg is not None
  137. return self._next_label_reg
  138. @next_label_reg.setter
  139. def next_label_reg(self, reg: Value) -> None:
  140. self._next_label_reg = reg
  141. @property
  142. def next_label_target(self) -> AssignmentTarget:
  143. assert self._next_label_target is not None
  144. return self._next_label_target
  145. @next_label_target.setter
  146. def next_label_target(self, target: AssignmentTarget) -> None:
  147. self._next_label_target = target