py: Define and use MP_OBJ_ITER_BUF_NSLOTS to get size of stack iter buf.

It improves readability of code and reduces the chance to make a mistake.

This patch also fixes a bug with nan-boxing builds by rounding up the
calculation of the new NSLOTS variable, giving the correct number of slots
(being 4) even if mp_obj_t is larger than the native machine size.
This commit is contained in:
Damien George
2017-03-23 16:36:08 +11:00
parent 507119f4d8
commit 60656eaea4
5 changed files with 24 additions and 18 deletions

23
py/vm.c
View File

@@ -684,7 +684,7 @@ unwind_jump:;
if (unum != 0) {
// pop iter and iter_buf
sp--;
sp -= sizeof(mp_obj_iter_buf_t) / sizeof(mp_obj_t);
sp -= MP_OBJ_ITER_BUF_NSLOTS;
}
DISPATCH_WITH_PEND_EXC_CHECK();
}
@@ -729,19 +729,20 @@ unwind_jump:;
SET_TOP(mp_getiter(TOP(), NULL));
DISPATCH();
// An iterator for a for-loop takes 4 slots on the stack. They are either
// used to store the iterator object itself, or the first slot is NULL and
// An iterator for a for-loop takes MP_OBJ_ITER_BUF_NSLOTS slots on
// the Python value stack. These slots are either used to store the
// iterator object itself, or the first slot is MP_OBJ_NULL and
// the second slot holds a reference to the iterator object.
ENTRY(MP_BC_GET_ITER_STACK): {
MARK_EXC_IP_SELECTIVE();
mp_obj_t obj = TOP();
mp_obj_iter_buf_t *iter_buf = (mp_obj_iter_buf_t*)sp;
sp += sizeof(mp_obj_iter_buf_t) / sizeof(mp_obj_t) - 1;
sp += MP_OBJ_ITER_BUF_NSLOTS - 1;
obj = mp_getiter(obj, iter_buf);
if (obj != MP_OBJ_FROM_PTR(iter_buf)) {
// Iterator didn't use the stack so indicate that with MP_OBJ_NULL.
sp[-3] = MP_OBJ_NULL;
sp[-2] = obj;
sp[-MP_OBJ_ITER_BUF_NSLOTS + 1] = MP_OBJ_NULL;
sp[-MP_OBJ_ITER_BUF_NSLOTS + 2] = obj;
}
DISPATCH();
}
@@ -751,14 +752,14 @@ unwind_jump:;
DECODE_ULABEL; // the jump offset if iteration finishes; for labels are always forward
code_state->sp = sp;
mp_obj_t obj;
if (sp[-3] == MP_OBJ_NULL) {
obj = sp[-2];
if (sp[-MP_OBJ_ITER_BUF_NSLOTS + 1] == MP_OBJ_NULL) {
obj = sp[-MP_OBJ_ITER_BUF_NSLOTS + 2];
} else {
obj = MP_OBJ_FROM_PTR(&sp[-3]);
obj = MP_OBJ_FROM_PTR(&sp[-MP_OBJ_ITER_BUF_NSLOTS + 1]);
}
mp_obj_t value = mp_iternext_allow_raise(obj);
if (value == MP_OBJ_STOP_ITERATION) {
sp -= 4; // pop the exhausted iterator
sp -= MP_OBJ_ITER_BUF_NSLOTS; // pop the exhausted iterator
ip += ulab; // jump to after for-block
} else {
PUSH(value); // push the next iteration value
@@ -1334,7 +1335,7 @@ exception_handler:
const byte *ip = code_state->ip + 1;
DECODE_ULABEL; // the jump offset if iteration finishes; for labels are always forward
code_state->ip = ip + ulab; // jump to after for-block
code_state->sp -= 4; // pop the exhausted iterator
code_state->sp -= MP_OBJ_ITER_BUF_NSLOTS; // pop the exhausted iterator
goto outer_dispatch_loop; // continue with dispatch loop
} else if (*code_state->ip == MP_BC_YIELD_FROM) {
// StopIteration inside yield from call means return a value of