bpo-27129: Use instruction offsets, not byte offsets, in bytecode and internally. (GH-25069)

* Use instruction offset, rather than bytecode offset. Streamlines interpreter dispatch a bit, and removes most EXTENDED_ARGs for jumps.

* Change some uses of PyCode_Addr2Line to PyFrame_GetLineNumber
diff --git a/Objects/codeobject.c b/Objects/codeobject.c
index 69cb31c..9bb49f1 100644
--- a/Objects/codeobject.c
+++ b/Objects/codeobject.c
@@ -1246,7 +1246,7 @@ PyTypeObject PyCode_Type = {
 int
 PyCode_Addr2Line(PyCodeObject *co, int addrq)
 {
-    if (addrq == -1) {
+    if (addrq < 0) {
         return co->co_firstlineno;
     }
     assert(addrq >= 0 && addrq < PyBytes_GET_SIZE(co->co_code));
diff --git a/Objects/frameobject.c b/Objects/frameobject.c
index a1413d7..9687ba5 100644
--- a/Objects/frameobject.c
+++ b/Objects/frameobject.c
@@ -15,7 +15,6 @@ static PyMemberDef frame_memberlist[] = {
     {"f_code",          T_OBJECT,       OFF(f_code),      READONLY},
     {"f_builtins",      T_OBJECT,       OFF(f_builtins),  READONLY},
     {"f_globals",       T_OBJECT,       OFF(f_globals),   READONLY},
-    {"f_lasti",         T_INT,          OFF(f_lasti),     READONLY},
     {"f_trace_lines",   T_BOOL,         OFF(f_trace_lines), 0},
     {"f_trace_opcodes", T_BOOL,         OFF(f_trace_opcodes), 0},
     {NULL}      /* Sentinel */
@@ -46,7 +45,7 @@ PyFrame_GetLineNumber(PyFrameObject *f)
         return f->f_lineno;
     }
     else {
-        return PyCode_Addr2Line(f->f_code, f->f_lasti);
+        return PyCode_Addr2Line(f->f_code, f->f_lasti*2);
     }
 }
 
@@ -56,6 +55,15 @@ frame_getlineno(PyFrameObject *f, void *closure)
     return PyLong_FromLong(PyFrame_GetLineNumber(f));
 }
 
+static PyObject *
+frame_getlasti(PyFrameObject *f, void *closure)
+{
+    if (f->f_lasti < 0) {
+        return PyLong_FromLong(-1);
+    }
+    return PyLong_FromLong(f->f_lasti*2);
+}
+
 
 /* Given the index of the effective opcode,
    scan back to construct the oparg with EXTENDED_ARG */
@@ -135,7 +143,7 @@ markblocks(PyCodeObject *code_obj, int len)
                 case POP_JUMP_IF_FALSE:
                 case POP_JUMP_IF_TRUE:
                 case JUMP_IF_NOT_EXC_MATCH:
-                    j = get_arg(code, i) / sizeof(_Py_CODEUNIT);
+                    j = get_arg(code, i);
                     assert(j < len);
                     if (blocks[j] == -1 && j < i) {
                         todo = 1;
@@ -145,7 +153,7 @@ markblocks(PyCodeObject *code_obj, int len)
                     blocks[i+1] = block_stack;
                     break;
                 case JUMP_ABSOLUTE:
-                    j = get_arg(code, i) / sizeof(_Py_CODEUNIT);
+                    j = get_arg(code, i);
                     assert(j < len);
                     if (blocks[j] == -1 && j < i) {
                         todo = 1;
@@ -154,7 +162,7 @@ markblocks(PyCodeObject *code_obj, int len)
                     blocks[j] = block_stack;
                     break;
                 case SETUP_FINALLY:
-                    j = get_arg(code, i) / sizeof(_Py_CODEUNIT) + i + 1;
+                    j = get_arg(code, i) + i + 1;
                     assert(j < len);
                     except_stack = push_block(block_stack, Except);
                     assert(blocks[j] == -1 || blocks[j] == except_stack);
@@ -164,7 +172,7 @@ markblocks(PyCodeObject *code_obj, int len)
                     break;
                 case SETUP_WITH:
                 case SETUP_ASYNC_WITH:
-                    j = get_arg(code, i) / sizeof(_Py_CODEUNIT) + i + 1;
+                    j = get_arg(code, i) + i + 1;
                     assert(j < len);
                     except_stack = push_block(block_stack, Except);
                     assert(blocks[j] == -1 || blocks[j] == except_stack);
@@ -173,7 +181,7 @@ markblocks(PyCodeObject *code_obj, int len)
                     blocks[i+1] = block_stack;
                     break;
                 case JUMP_FORWARD:
-                    j = get_arg(code, i) / sizeof(_Py_CODEUNIT) + i + 1;
+                    j = get_arg(code, i) + i + 1;
                     assert(j < len);
                     assert(blocks[j] == -1 || blocks[j] == block_stack);
                     blocks[j] = block_stack;
@@ -186,7 +194,7 @@ markblocks(PyCodeObject *code_obj, int len)
                 case FOR_ITER:
                     blocks[i+1] = block_stack;
                     block_stack = pop_block(block_stack);
-                    j = get_arg(code, i) / sizeof(_Py_CODEUNIT) + i + 1;
+                    j = get_arg(code, i) + i + 1;
                     assert(j < len);
                     assert(blocks[j] == -1 || blocks[j] == block_stack);
                     blocks[j] = block_stack;
@@ -422,7 +430,7 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno, void *Py_UNUSED(ignore
     int64_t target_block_stack = -1;
     int64_t best_block_stack = -1;
     int best_addr = -1;
-    int64_t start_block_stack = blocks[f->f_lasti/sizeof(_Py_CODEUNIT)];
+    int64_t start_block_stack = blocks[f->f_lasti];
     const char *msg = "cannot find bytecode for specified line";
     for (int i = 0; i < len; i++) {
         if (lines[i] == new_lineno) {
@@ -431,7 +439,7 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno, void *Py_UNUSED(ignore
                 msg = NULL;
                 if (target_block_stack > best_block_stack) {
                     best_block_stack = target_block_stack;
-                    best_addr = i*sizeof(_Py_CODEUNIT);
+                    best_addr = i;
                 }
             }
             else if (msg) {
@@ -511,6 +519,7 @@ static PyGetSetDef frame_getsetlist[] = {
     {"f_lineno",        (getter)frame_getlineno,
                     (setter)frame_setlineno, NULL},
     {"f_trace",         (getter)frame_gettrace, (setter)frame_settrace, NULL},
+    {"f_lasti",         (getter)frame_getlasti, NULL, NULL},
     {0}
 };
 
diff --git a/Objects/genobject.c b/Objects/genobject.c
index 26e27cc..6998967 100644
--- a/Objects/genobject.c
+++ b/Objects/genobject.c
@@ -357,7 +357,7 @@ _PyGen_yf(PyGenObject *gen)
             return NULL;
         }
 
-        if (code[f->f_lasti + sizeof(_Py_CODEUNIT)] != YIELD_FROM)
+        if (code[(f->f_lasti+1)*sizeof(_Py_CODEUNIT)] != YIELD_FROM)
             return NULL;
         assert(f->f_stackdepth > 0);
         yf = f->f_valuestack[f->f_stackdepth-1];
@@ -481,7 +481,7 @@ _gen_throw(PyGenObject *gen, int close_on_genexit,
             Py_DECREF(ret);
             /* Termination repetition of YIELD_FROM */
             assert(gen->gi_frame->f_lasti >= 0);
-            gen->gi_frame->f_lasti += sizeof(_Py_CODEUNIT);
+            gen->gi_frame->f_lasti += 1;
             if (_PyGen_FetchStopIterationValue(&val) == 0) {
                 ret = gen_send(gen, val);
                 Py_DECREF(val);