Skip to content

Commit 49159ef

Browse files
committed
py/objcode: Implement co_lines method.
Signed-off-by: Anson Mansfield <amansfield@mantaro.com>
1 parent 4b6d108 commit 49159ef

File tree

1 file changed

+65
-0
lines changed

1 file changed

+65
-0
lines changed

py/objcode.c

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,67 @@ static mp_obj_t raw_code_lnotab(const mp_raw_code_t *rc) {
107107
return o;
108108
}
109109

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+
110171
static void code_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
111172
if (dest[0] != MP_OBJ_NULL) {
112173
// not load attribute
@@ -143,6 +204,10 @@ static void code_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
143204
}
144205
dest[0] = o->lnotab;
145206
break;
207+
case MP_QSTR_co_lines:
208+
dest[0] = MP_OBJ_FROM_PTR(&code_colines_obj);
209+
dest[1] = self_in;
210+
break;
146211
}
147212
}
148213

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy