(
self, expr_reg: Value, target_type: RType, reverse: bool, length: Value | None = None
)
| 886 | length_reg: Value | AssignmentTarget | None |
| 887 | |
| 888 | def init( |
| 889 | self, expr_reg: Value, target_type: RType, reverse: bool, length: Value | None = None |
| 890 | ) -> None: |
| 891 | assert is_sequence_rprimitive(expr_reg.type) or isinstance(expr_reg.type, RVec), ( |
| 892 | expr_reg, |
| 893 | expr_reg.type, |
| 894 | ) |
| 895 | builder = self.builder |
| 896 | # Record a Value indicating the length of the sequence, if known at compile time. |
| 897 | self.length = length |
| 898 | self.reverse = reverse |
| 899 | # Define target to contain the expression, along with the index that will be used |
| 900 | # for the for-loop. If we are inside of a generator function, spill these into the |
| 901 | # environment class. |
| 902 | self.expr_target = builder.maybe_spill(expr_reg) |
| 903 | if is_immutable_rprimitive(expr_reg.type): |
| 904 | # If the expression is an immutable type, we can load the length just once. |
| 905 | self.length_reg = builder.maybe_spill(self.length or self.load_len(self.expr_target)) |
| 906 | else: |
| 907 | # Otherwise, even if the length is known, we must recalculate the length |
| 908 | # at every iteration for compatibility with python semantics. |
| 909 | self.length_reg = None |
| 910 | if not reverse: |
| 911 | index_reg: Value = Integer(0, c_pyssize_t_rprimitive) |
| 912 | else: |
| 913 | if self.length_reg is not None: |
| 914 | len_val = builder.read(self.length_reg, self.line) |
| 915 | else: |
| 916 | len_val = self.load_len(self.expr_target) |
| 917 | index_reg = builder.builder.int_sub(len_val, 1) |
| 918 | self.index_target = builder.maybe_spill_assignable(index_reg) |
| 919 | self.target_type = target_type |
| 920 | |
| 921 | def gen_condition(self) -> None: |
| 922 | builder = self.builder |
no test coverage detected