@@ -107,6 +107,67 @@ static mp_obj_t raw_code_lnotab(const mp_raw_code_t *rc) {
107
107
return o ;
108
108
}
109
109
110
+ static mp_obj_t code_colines_iter (mp_obj_t );
111
+ static mp_obj_t code_colines_next (mp_obj_t );
112
+ typedef struct _mp_obj_colines_iter_t {
113
+ mp_obj_base_t base ;
114
+ mp_fun_1_t iternext ;
115
+ const mp_raw_code_t * rc ;
116
+ mp_uint_t bc ;
117
+ mp_uint_t source_line ;
118
+ const byte * ci ;
119
+ } mp_obj_colines_iter_t ;
120
+
121
+ static mp_obj_t code_colines_iter (mp_obj_t self_in ) {
122
+ mp_obj_code_t * self = MP_OBJ_TO_PTR (self_in );
123
+ mp_obj_colines_iter_t * iter = mp_obj_malloc (mp_obj_colines_iter_t , & mp_type_polymorph_iter );
124
+ iter -> iternext = code_colines_next ;
125
+ iter -> rc = self -> rc ;
126
+ iter -> bc = 0 ;
127
+ iter -> source_line = 1 ;
128
+ iter -> ci = self -> rc -> prelude .line_info ;
129
+ return MP_OBJ_FROM_PTR (iter );
130
+ }
131
+ static MP_DEFINE_CONST_FUN_OBJ_1 (code_colines_obj , code_colines_iter ) ;
132
+
133
+ static mp_obj_t code_colines_next (mp_obj_t iter_in ) {
134
+ mp_obj_colines_iter_t * iter = MP_OBJ_TO_PTR (iter_in );
135
+ const byte * ci_end = iter -> rc -> prelude .line_info_top ;
136
+
137
+ mp_uint_t start = iter -> bc ;
138
+ mp_uint_t line_no = iter -> source_line ;
139
+ bool another = true;
140
+
141
+ while (another && iter -> ci < ci_end ) {
142
+ another = false;
143
+ mp_code_lineinfo_t decoded = mp_bytecode_decode_lineinfo (& iter -> ci );
144
+ iter -> bc += decoded .bc_increment ;
145
+ iter -> source_line += decoded .line_increment ;
146
+
147
+ if (decoded .bc_increment == 0 ) {
148
+ line_no = iter -> source_line ;
149
+ another = true;
150
+ } else if (decoded .line_increment == 0 ) {
151
+ another = true;
152
+ }
153
+ }
154
+
155
+ if (another ) {
156
+ mp_uint_t prelude_size = (iter -> rc -> prelude .opcodes - (const byte * )iter -> rc -> fun_data );
157
+ mp_uint_t bc_end = iter -> rc -> fun_data_len - prelude_size ;
158
+ if (iter -> bc >= bc_end ) {
159
+ return MP_OBJ_STOP_ITERATION ;
160
+ } else {
161
+ iter -> bc = bc_end ;
162
+ }
163
+ }
164
+
165
+ mp_uint_t end = iter -> bc ;
166
+ mp_obj_t next [3 ] = {MP_OBJ_NEW_SMALL_INT (start ), MP_OBJ_NEW_SMALL_INT (end ), MP_OBJ_NEW_SMALL_INT (line_no )};
167
+
168
+ return mp_obj_new_tuple (MP_ARRAY_SIZE (next ), next );
169
+ }
170
+
110
171
static void code_attr (mp_obj_t self_in , qstr attr , mp_obj_t * dest ) {
111
172
if (dest [0 ] != MP_OBJ_NULL ) {
112
173
// not load attribute
@@ -143,6 +204,10 @@ static void code_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
143
204
}
144
205
dest [0 ] = o -> lnotab ;
145
206
break ;
207
+ case MP_QSTR_co_lines :
208
+ dest [0 ] = MP_OBJ_FROM_PTR (& code_colines_obj );
209
+ dest [1 ] = self_in ;
210
+ break ;
146
211
}
147
212
}
148
213
0 commit comments