示例#1
0
文件: util.c 项目: Orav/kbengine
sqlite_int64
_pysqlite_long_as_int64(PyObject * py_val)
{
    int overflow;
#ifdef HAVE_LONG_LONG
    PY_LONG_LONG value = PyLong_AsLongLongAndOverflow(py_val, &overflow);
#else
    long value = PyLong_AsLongAndOverflow(py_val, &overflow);
#endif
    if (value == -1 && PyErr_Occurred())
        return -1;
    if (!overflow) {
#ifdef HAVE_LONG_LONG
# if SIZEOF_LONG_LONG > 8
        if (-0x8000000000000000LL <= value && value <= 0x7FFFFFFFFFFFFFFFLL)
# endif
#else
# if SIZEOF_LONG > 8
        if (-0x8000000000000000L <= value && value <= 0x7FFFFFFFFFFFFFFFL)
# endif
#endif
            return value;
    }
    else if (sizeof(value) < sizeof(sqlite_int64)) {
        sqlite_int64 int64val;
        if (_PyLong_AsByteArray((PyLongObject *)py_val,
                                (unsigned char *)&int64val, sizeof(int64val),
                                IS_LITTLE_ENDIAN, 1 /* signed */) >= 0) {
            return int64val;
        }
    }
    PyErr_SetString(PyExc_OverflowError,
                    "Python int too large to convert to SQLite INTEGER");
    return -1;
}
示例#2
0
PyObject *
PyGcc_int_from_decimal_string_buffer(const char *buf)
{
    PyObject *long_obj;
#if PY_MAJOR_VERSION < 3
    long long_val;
    int overflow;
#endif
    long_obj = PyLong_FromString((char *)buf, NULL, 10);
    if (!long_obj) {
        return NULL;
    }
#if PY_MAJOR_VERSION >= 3
    return long_obj;
#else
    long_val = PyLong_AsLongAndOverflow(long_obj, &overflow);
    if (overflow) {
        /* Doesn't fit in a PyIntObject; use the PyLongObject: */
        return long_obj;
    } else {
        /* Fits in a PyIntObject: use that */
        PyObject *int_obj = PyInt_FromLong(long_val);
        if (!int_obj) {
            return long_obj;
        }
        Py_DECREF(long_obj);
        return int_obj;
    }
#endif
}
示例#3
0
int
PyTraceBack_Print(PyObject *v, PyObject *f)
{
    int err;
    PyObject *limitv;
    long limit = PyTraceBack_LIMIT;

    if (v == NULL)
        return 0;
    if (!PyTraceBack_Check(v)) {
        PyErr_BadInternalCall();
        return -1;
    }
    limitv = PySys_GetObject("tracebacklimit");
    if (limitv && PyLong_Check(limitv)) {
        int overflow;
        limit = PyLong_AsLongAndOverflow(limitv, &overflow);
        if (overflow > 0) {
            limit = LONG_MAX;
        }
        else if (limit <= 0) {
            return 0;
        }
    }
    err = PyFile_WriteString("Traceback (most recent call last):\n", f);
    if (!err)
        err = tb_printinternal((PyTracebackObject *)v, f, limit);
    return err;
}
示例#4
0
PyObject *
gcc_python_int_from_double_int(double_int di, bool is_unsigned)
{
    PyObject *long_obj;
#if PY_MAJOR_VERSION < 3
    long long_val;
    int overflow;
#endif
    char buf[512]; /* FIXME */
    gcc_python_double_int_as_text(di, is_unsigned, buf, sizeof(buf));

    long_obj = PyLong_FromString(buf, NULL, 10);
    if (!long_obj) {
        return NULL;
    }
#if PY_MAJOR_VERSION >= 3
    return long_obj;
#else
    long_val = PyLong_AsLongAndOverflow(long_obj, &overflow);
    if (overflow) {
        /* Doesn't fit in a PyIntObject; use the PyLongObject: */
        return long_obj;
    } else {
        /* Fits in a PyIntObject: use that */
        PyObject *int_obj = PyInt_FromLong(long_val);
        if (!int_obj) {
            return long_obj;
        }
        Py_DECREF(long_obj);
        return int_obj;
    }
#endif
}
示例#5
0
 T_ FromPyLong(PyObject* pyLong)
 {
     int overflow = 0;
     long long_result = PyLong_AsLongAndOverflow(pyLong, &overflow);
     NATIVE_CHECK(!overflow, "long value overflow");
     T_ result = static_cast<T_>(long_result);
     NATIVE_CHECK(static_cast<long>(result) == long_result, "T_ value overflow");
     return result;
 }
示例#6
0
文件: long.cpp 项目: lameiro/pyston
extern "C" long PyLong_AsLong(PyObject* vv) noexcept {
    int overflow;
    long result = PyLong_AsLongAndOverflow(vv, &overflow);
    if (overflow) {
        /* XXX: could be cute and give a different
           message for overflow == -1 */
        PyErr_SetString(PyExc_OverflowError, "Python int too large to convert to C long");
    }
    return result;
}
示例#7
0
文件: long.cpp 项目: lameiro/pyston
extern "C" int _PyLong_AsInt(PyObject* obj) noexcept {
    int overflow;
    long result = PyLong_AsLongAndOverflow(obj, &overflow);
    if (overflow || result > INT_MAX || result < INT_MIN) {
        /* XXX: could be cute and give a different
           message for overflow == -1 */
        PyErr_SetString(PyExc_OverflowError, "Python int too large to convert to C int");
        return -1;
    }
    return (int)result;
}
示例#8
0
static int fd_converter(PyObject *o, void *p)
{
	int *fd = p;
	long tmp;
	int overflow;

	tmp = PyLong_AsLongAndOverflow(o, &overflow);
	if (tmp == -1 && PyErr_Occurred())
		return 0;
	if (overflow > 0 || tmp > INT_MAX) {
		PyErr_SetString(PyExc_OverflowError,
				"fd is greater than maximum");
		return 0;
	}
	if (overflow < 0 || tmp < 0) {
		PyErr_SetString(PyExc_ValueError, "fd is negative");
		return 0;
	}
	*fd = tmp;
	return 1;
}
示例#9
0
static int isOne(PyObject* obj)
{
    int overflow = 0;
    long temp;
    
    if (!obj)
        return 1;

    if (Pympq_Check(obj)) {
        return (0==mpz_cmp_ui(mpq_denref(Pympq_AS_MPQ(obj)),1)) &&
               (0==mpz_cmp_ui(mpq_numref(Pympq_AS_MPQ(obj)),1));
    }
    else if (Pympz_Check(obj)) {
        return 0==mpz_cmp_ui(Pympz_AS_MPZ(obj),1);
    }
    else if (Pyxmpz_Check(obj)) {
        return 0==mpz_cmp_ui(Pyxmpz_AS_MPZ(obj),1);
#ifdef PY2
    }
    else if (PyInt_Check(obj)) {
        return PyInt_AS_LONG(obj)==1;
#endif
    }
#ifdef WITHMPFR
    else if (Pympfr_Check(obj)) {
        return mpfr_get_d(Pympfr_AS_MPFR(obj), context->ctx.mpfr_round)==1.0;
    }
#endif
    else if (PyFloat_Check(obj)) {
        return PyFloat_AS_DOUBLE(obj)==1.0;
    }
    else if (PyLong_Check(obj)) {
        temp = PyLong_AsLongAndOverflow(obj, &overflow);
        if (!overflow && temp == 1)
            return 1;
        else
            return 0;
    }
    return 0;
}
示例#10
0
/* Setter for f_lineno - you can set f_lineno from within a trace function in
 * order to jump to a given line of code, subject to some restrictions.  Most
 * lines are OK to jump to because they don't make any assumptions about the
 * state of the stack (obvious because you could remove the line and the code
 * would still work without any stack errors), but there are some constructs
 * that limit jumping:
 *
 *  o Lines with an 'except' statement on them can't be jumped to, because
 *    they expect an exception to be on the top of the stack.
 *  o Lines that live in a 'finally' block can't be jumped from or to, since
 *    the END_FINALLY expects to clean up the stack after the 'try' block.
 *  o 'try'/'for'/'while' blocks can't be jumped into because the blockstack
 *    needs to be set up before their code runs, and for 'for' loops the
 *    iterator needs to be on the stack.
 */
static int
frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno)
{
    int new_lineno = 0;                 /* The new value of f_lineno */
    long l_new_lineno;
    int overflow;
    int new_lasti = 0;                  /* The new value of f_lasti */
    int new_iblock = 0;                 /* The new value of f_iblock */
    unsigned char *code = NULL;         /* The bytecode for the frame... */
    Py_ssize_t code_len = 0;            /* ...and its length */
    unsigned char *lnotab = NULL;       /* Iterating over co_lnotab */
    Py_ssize_t lnotab_len = 0;          /* (ditto) */
    int offset = 0;                     /* (ditto) */
    int line = 0;                       /* (ditto) */
    int addr = 0;                       /* (ditto) */
    int min_addr = 0;                   /* Scanning the SETUPs and POPs */
    int max_addr = 0;                   /* (ditto) */
    int delta_iblock = 0;               /* (ditto) */
    int min_delta_iblock = 0;           /* (ditto) */
    int min_iblock = 0;                 /* (ditto) */
    int f_lasti_setup_addr = 0;         /* Policing no-jump-into-finally */
    int new_lasti_setup_addr = 0;       /* (ditto) */
    int blockstack[CO_MAXBLOCKS];       /* Walking the 'finally' blocks */
    int in_finally[CO_MAXBLOCKS];       /* (ditto) */
    int blockstack_top = 0;             /* (ditto) */
    unsigned char setup_op = 0;         /* (ditto) */

    /* f_lineno must be an integer. */
    if (!PyLong_CheckExact(p_new_lineno)) {
        PyErr_SetString(PyExc_ValueError,
                        "lineno must be an integer");
        return -1;
    }

    /* You can only do this from within a trace function, not via
     * _getframe or similar hackery. */
    if (!f->f_trace)
    {
        PyErr_Format(PyExc_ValueError,
                     "f_lineno can only be set by a"
                     " line trace function");
        return -1;
    }

    /* Fail if the line comes before the start of the code block. */
    l_new_lineno = PyLong_AsLongAndOverflow(p_new_lineno, &overflow);
    if (overflow
#if SIZEOF_LONG > SIZEOF_INT
        || l_new_lineno > INT_MAX
        || l_new_lineno < INT_MIN
#endif
       ) {
        PyErr_SetString(PyExc_ValueError,
                        "lineno out of range");
        return -1;
    }
    new_lineno = (int)l_new_lineno;

    if (new_lineno < f->f_code->co_firstlineno) {
        PyErr_Format(PyExc_ValueError,
                     "line %d comes before the current code block",
                     new_lineno);
        return -1;
    }
    else if (new_lineno == f->f_code->co_firstlineno) {
        new_lasti = 0;
        new_lineno = f->f_code->co_firstlineno;
    }
    else {
        /* Find the bytecode offset for the start of the given
         * line, or the first code-owning line after it. */
        char *tmp;
        PyBytes_AsStringAndSize(f->f_code->co_lnotab,
                                &tmp, &lnotab_len);
        lnotab = (unsigned char *) tmp;
        addr = 0;
        line = f->f_code->co_firstlineno;
        new_lasti = -1;
        for (offset = 0; offset < lnotab_len; offset += 2) {
            addr += lnotab[offset];
            line += lnotab[offset+1];
            if (line >= new_lineno) {
                new_lasti = addr;
                new_lineno = line;
                break;
            }
        }
    }

    /* If we didn't reach the requested line, return an error. */
    if (new_lasti == -1) {
        PyErr_Format(PyExc_ValueError,
                     "line %d comes after the current code block",
                     new_lineno);
        return -1;
    }

    /* We're now ready to look at the bytecode. */
    PyBytes_AsStringAndSize(f->f_code->co_code, (char **)&code, &code_len);
    min_addr = Py_MIN(new_lasti, f->f_lasti);
    max_addr = Py_MAX(new_lasti, f->f_lasti);

    /* You can't jump onto a line with an 'except' statement on it -
     * they expect to have an exception on the top of the stack, which
     * won't be true if you jump to them.  They always start with code
     * that either pops the exception using POP_TOP (plain 'except:'
     * lines do this) or duplicates the exception on the stack using
     * DUP_TOP (if there's an exception type specified).  See compile.c,
     * 'com_try_except' for the full details.  There aren't any other
     * cases (AFAIK) where a line's code can start with DUP_TOP or
     * POP_TOP, but if any ever appear, they'll be subject to the same
     * restriction (but with a different error message). */
    if (code[new_lasti] == DUP_TOP || code[new_lasti] == POP_TOP) {
        PyErr_SetString(PyExc_ValueError,
            "can't jump to 'except' line as there's no exception");
        return -1;
    }

    /* You can't jump into or out of a 'finally' block because the 'try'
     * block leaves something on the stack for the END_FINALLY to clean
     * up.      So we walk the bytecode, maintaining a simulated blockstack.
     * When we reach the old or new address and it's in a 'finally' block
     * we note the address of the corresponding SETUP_FINALLY.  The jump
     * is only legal if neither address is in a 'finally' block or
     * they're both in the same one.  'blockstack' is a stack of the
     * bytecode addresses of the SETUP_X opcodes, and 'in_finally' tracks
     * whether we're in a 'finally' block at each blockstack level. */
    f_lasti_setup_addr = -1;
    new_lasti_setup_addr = -1;
    memset(blockstack, '\0', sizeof(blockstack));
    memset(in_finally, '\0', sizeof(in_finally));
    blockstack_top = 0;
    for (addr = 0; addr < code_len; addr++) {
        unsigned char op = code[addr];
        switch (op) {
        case SETUP_LOOP:
        case SETUP_EXCEPT:
        case SETUP_FINALLY:
        case SETUP_WITH:
            blockstack[blockstack_top++] = addr;
            in_finally[blockstack_top-1] = 0;
            break;

        case POP_BLOCK:
            assert(blockstack_top > 0);
            setup_op = code[blockstack[blockstack_top-1]];
            if (setup_op == SETUP_FINALLY || setup_op == SETUP_WITH) {
                in_finally[blockstack_top-1] = 1;
            }
            else {
                blockstack_top--;
            }
            break;

        case END_FINALLY:
            /* Ignore END_FINALLYs for SETUP_EXCEPTs - they exist
             * in the bytecode but don't correspond to an actual
             * 'finally' block.  (If blockstack_top is 0, we must
             * be seeing such an END_FINALLY.) */
            if (blockstack_top > 0) {
                setup_op = code[blockstack[blockstack_top-1]];
                if (setup_op == SETUP_FINALLY || setup_op == SETUP_WITH) {
                    blockstack_top--;
                }
            }
            break;
        }

        /* For the addresses we're interested in, see whether they're
         * within a 'finally' block and if so, remember the address
         * of the SETUP_FINALLY. */
        if (addr == new_lasti || addr == f->f_lasti) {
            int i = 0;
            int setup_addr = -1;
            for (i = blockstack_top-1; i >= 0; i--) {
                if (in_finally[i]) {
                    setup_addr = blockstack[i];
                    break;
                }
            }

            if (setup_addr != -1) {
                if (addr == new_lasti) {
                    new_lasti_setup_addr = setup_addr;
                }

                if (addr == f->f_lasti) {
                    f_lasti_setup_addr = setup_addr;
                }
            }
        }

        if (op >= HAVE_ARGUMENT) {
            addr += 2;
        }
    }

    /* Verify that the blockstack tracking code didn't get lost. */
    assert(blockstack_top == 0);

    /* After all that, are we jumping into / out of a 'finally' block? */
    if (new_lasti_setup_addr != f_lasti_setup_addr) {
        PyErr_SetString(PyExc_ValueError,
                    "can't jump into or out of a 'finally' block");
        return -1;
    }


    /* Police block-jumping (you can't jump into the middle of a block)
     * and ensure that the blockstack finishes up in a sensible state (by
     * popping any blocks we're jumping out of).  We look at all the
     * blockstack operations between the current position and the new
     * one, and keep track of how many blocks we drop out of on the way.
     * By also keeping track of the lowest blockstack position we see, we
     * can tell whether the jump goes into any blocks without coming out
     * again - in that case we raise an exception below. */
    delta_iblock = 0;
    for (addr = min_addr; addr < max_addr; addr++) {
        unsigned char op = code[addr];
        switch (op) {
        case SETUP_LOOP:
        case SETUP_EXCEPT:
        case SETUP_FINALLY:
        case SETUP_WITH:
            delta_iblock++;
            break;

        case POP_BLOCK:
            delta_iblock--;
            break;
        }

        min_delta_iblock = Py_MIN(min_delta_iblock, delta_iblock);

        if (op >= HAVE_ARGUMENT) {
            addr += 2;
        }
    }

    /* Derive the absolute iblock values from the deltas. */
    min_iblock = f->f_iblock + min_delta_iblock;
    if (new_lasti > f->f_lasti) {
        /* Forwards jump. */
        new_iblock = f->f_iblock + delta_iblock;
    }
    else {
        /* Backwards jump. */
        new_iblock = f->f_iblock - delta_iblock;
    }

    /* Are we jumping into a block? */
    if (new_iblock > min_iblock) {
        PyErr_SetString(PyExc_ValueError,
                        "can't jump into the middle of a block");
        return -1;
    }

    /* Pop any blocks that we're jumping out of. */
    while (f->f_iblock > new_iblock) {
        PyTryBlock *b = &f->f_blockstack[--f->f_iblock];
        while ((f->f_stacktop - f->f_valuestack) > b->b_level) {
            PyObject *v = (*--f->f_stacktop);
            Py_DECREF(v);
        }
    }

    /* Finally set the new f_lineno and f_lasti and return OK. */
    f->f_lineno = new_lineno;
    f->f_lasti = new_lasti;
    return 0;
}
示例#11
0
/* Setter for f_lineno - you can set f_lineno from within a trace function in
 * order to jump to a given line of code, subject to some restrictions.  Most
 * lines are OK to jump to because they don't make any assumptions about the
 * state of the stack (obvious because you could remove the line and the code
 * would still work without any stack errors), but there are some constructs
 * that limit jumping:
 *
 *  o Lines with an 'except' statement on them can't be jumped to, because
 *    they expect an exception to be on the top of the stack.
 *  o Lines that live in a 'finally' block can't be jumped from or to, since
 *    the END_FINALLY expects to clean up the stack after the 'try' block.
 *  o 'try', 'with' and 'async with' blocks can't be jumped into because
 *    the blockstack needs to be set up before their code runs.
 *  o 'for' and 'async for' loops can't be jumped into because the
 *    iterator needs to be on the stack.
 *  o Jumps cannot be made from within a trace function invoked with a
 *    'return' or 'exception' event since the eval loop has been exited at
 *    that time.
 */
static int
frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno, void *Py_UNUSED(ignored))
{
    int new_lineno = 0;                 /* The new value of f_lineno */
    long l_new_lineno;
    int overflow;
    int new_lasti = 0;                  /* The new value of f_lasti */
    unsigned char *code = NULL;         /* The bytecode for the frame... */
    Py_ssize_t code_len = 0;            /* ...and its length */
    unsigned char *lnotab = NULL;       /* Iterating over co_lnotab */
    Py_ssize_t lnotab_len = 0;          /* (ditto) */
    int offset = 0;                     /* (ditto) */
    int line = 0;                       /* (ditto) */
    int addr = 0;                       /* (ditto) */
    int delta_iblock = 0;               /* Scanning the SETUPs and POPs */
    int delta = 0;
    int blockstack[CO_MAXBLOCKS];       /* Walking the 'finally' blocks */
    int blockstack_top = 0;             /* (ditto) */

    /* f_lineno must be an integer. */
    if (!PyLong_CheckExact(p_new_lineno)) {
        PyErr_SetString(PyExc_ValueError,
                        "lineno must be an integer");
        return -1;
    }

    /* Upon the 'call' trace event of a new frame, f->f_lasti is -1 and
     * f->f_trace is NULL, check first on the first condition.
     * Forbidding jumps from the 'call' event of a new frame is a side effect
     * of allowing to set f_lineno only from trace functions. */
    if (f->f_lasti == -1) {
        PyErr_Format(PyExc_ValueError,
                     "can't jump from the 'call' trace event of a new frame");
        return -1;
    }

    /* You can only do this from within a trace function, not via
     * _getframe or similar hackery. */
    if (!f->f_trace) {
        PyErr_Format(PyExc_ValueError,
                     "f_lineno can only be set by a trace function");
        return -1;
    }

    /* Forbid jumps upon a 'return' trace event (except after executing a
     * YIELD_VALUE or YIELD_FROM opcode, f_stacktop is not NULL in that case)
     * and upon an 'exception' trace event.
     * Jumps from 'call' trace events have already been forbidden above for new
     * frames, so this check does not change anything for 'call' events. */
    if (f->f_stacktop == NULL) {
        PyErr_SetString(PyExc_ValueError,
                "can only jump from a 'line' trace event");
        return -1;
    }

    /* Fail if the line comes before the start of the code block. */
    l_new_lineno = PyLong_AsLongAndOverflow(p_new_lineno, &overflow);
    if (overflow
#if SIZEOF_LONG > SIZEOF_INT
        || l_new_lineno > INT_MAX
        || l_new_lineno < INT_MIN
#endif
       ) {
        PyErr_SetString(PyExc_ValueError,
                        "lineno out of range");
        return -1;
    }
    new_lineno = (int)l_new_lineno;

    if (new_lineno < f->f_code->co_firstlineno) {
        PyErr_Format(PyExc_ValueError,
                     "line %d comes before the current code block",
                     new_lineno);
        return -1;
    }
    else if (new_lineno == f->f_code->co_firstlineno) {
        new_lasti = 0;
        new_lineno = f->f_code->co_firstlineno;
    }
    else {
        /* Find the bytecode offset for the start of the given
         * line, or the first code-owning line after it. */
        char *tmp;
        PyBytes_AsStringAndSize(f->f_code->co_lnotab,
                                &tmp, &lnotab_len);
        lnotab = (unsigned char *) tmp;
        addr = 0;
        line = f->f_code->co_firstlineno;
        new_lasti = -1;
        for (offset = 0; offset < lnotab_len; offset += 2) {
            addr += lnotab[offset];
            line += (signed char)lnotab[offset+1];
            if (line >= new_lineno) {
                new_lasti = addr;
                new_lineno = line;
                break;
            }
        }
    }

    /* If we didn't reach the requested line, return an error. */
    if (new_lasti == -1) {
        PyErr_Format(PyExc_ValueError,
                     "line %d comes after the current code block",
                     new_lineno);
        return -1;
    }

    /* We're now ready to look at the bytecode. */
    PyBytes_AsStringAndSize(f->f_code->co_code, (char **)&code, &code_len);

    /* The trace function is called with a 'return' trace event after the
     * execution of a yield statement. */
    assert(f->f_lasti != -1);
    if (code[f->f_lasti] == YIELD_VALUE || code[f->f_lasti] == YIELD_FROM) {
        PyErr_SetString(PyExc_ValueError,
                "can't jump from a yield statement");
        return -1;
    }

    /* You can't jump onto a line with an 'except' statement on it -
     * they expect to have an exception on the top of the stack, which
     * won't be true if you jump to them.  They always start with code
     * that either pops the exception using POP_TOP (plain 'except:'
     * lines do this) or duplicates the exception on the stack using
     * DUP_TOP (if there's an exception type specified).  See compile.c,
     * 'com_try_except' for the full details.  There aren't any other
     * cases (AFAIK) where a line's code can start with DUP_TOP or
     * POP_TOP, but if any ever appear, they'll be subject to the same
     * restriction (but with a different error message). */
    if (code[new_lasti] == DUP_TOP || code[new_lasti] == POP_TOP) {
        PyErr_SetString(PyExc_ValueError,
            "can't jump to 'except' line as there's no exception");
        return -1;
    }

    /* You can't jump into or out of a 'finally' block because the 'try'
     * block leaves something on the stack for the END_FINALLY to clean up.
     * So we walk the bytecode, maintaining a simulated blockstack.
     * 'blockstack' is a stack of the bytecode addresses of the starts of
     * the 'finally' blocks. */
    memset(blockstack, '\0', sizeof(blockstack));
    blockstack_top = 0;
    for (addr = 0; addr < code_len; addr += sizeof(_Py_CODEUNIT)) {
        unsigned char op = code[addr];
        switch (op) {
        case SETUP_FINALLY:
        case SETUP_WITH:
        case SETUP_ASYNC_WITH:
        case FOR_ITER: {
            unsigned int oparg = get_arg((const _Py_CODEUNIT *)code,
                                         addr / sizeof(_Py_CODEUNIT));
            int target_addr = addr + oparg + sizeof(_Py_CODEUNIT);
            assert(target_addr < code_len);
            /* Police block-jumping (you can't jump into the middle of a block)
             * and ensure that the blockstack finishes up in a sensible state (by
             * popping any blocks we're jumping out of).  We look at all the
             * blockstack operations between the current position and the new
             * one, and keep track of how many blocks we drop out of on the way.
             * By also keeping track of the lowest blockstack position we see, we
             * can tell whether the jump goes into any blocks without coming out
             * again - in that case we raise an exception below. */
            int first_in = addr < f->f_lasti && f->f_lasti < target_addr;
            int second_in = addr < new_lasti && new_lasti < target_addr;
            if (!first_in && second_in) {
                PyErr_SetString(PyExc_ValueError,
                                "can't jump into the middle of a block");
                return -1;
            }
            if (first_in && !second_in) {
                if (op != FOR_ITER && code[target_addr] != END_ASYNC_FOR) {
                    delta_iblock++;
                }
                else if (!delta_iblock) {
                    /* Pop the iterators of any 'for' and 'async for' loop
                     * we're jumping out of. */
                    delta++;
                }
            }
            if (op != FOR_ITER && code[target_addr] != END_ASYNC_FOR) {
                blockstack[blockstack_top++] = target_addr;
            }
            break;
        }

        case END_FINALLY: {
            assert(blockstack_top > 0);
            int target_addr = blockstack[--blockstack_top];
            assert(target_addr <= addr);
            int first_in = target_addr <= f->f_lasti && f->f_lasti <= addr;
            int second_in = target_addr <= new_lasti && new_lasti <= addr;
            if (first_in != second_in) {
                op = code[target_addr];
                PyErr_Format(PyExc_ValueError,
                             "can't jump %s %s block",
                             second_in ? "into" : "out of",
                             (op == DUP_TOP || op == POP_TOP) ?
                                "an 'except'" : "a 'finally'");
                return -1;
            }
            break;
        }
        }
    }

    /* Verify that the blockstack tracking code didn't get lost. */
    assert(blockstack_top == 0);

    /* Pop any blocks that we're jumping out of. */
    if (delta_iblock > 0) {
        f->f_iblock -= delta_iblock;
        PyTryBlock *b = &f->f_blockstack[f->f_iblock];
        delta += (int)(f->f_stacktop - f->f_valuestack) - b->b_level;
        if (b->b_type == SETUP_FINALLY &&
            code[b->b_handler] == WITH_CLEANUP_START)
        {
            /* Pop the exit function. */
            delta++;
        }
    }
    while (delta > 0) {
        PyObject *v = (*--f->f_stacktop);
        Py_DECREF(v);
        delta--;
    }

    /* Finally set the new f_lineno and f_lasti and return OK. */
    f->f_lineno = new_lineno;
    f->f_lasti = new_lasti;
    return 0;
}