#endif
#ifdef WITH_DTRACE
-#define OR_DTRACE_LINE || PyDTrace_LINE_ENABLED()
+#define OR_DTRACE_LINE | (PyDTrace_LINE_ENABLED() ? 255 : 0)
#else
#define OR_DTRACE_LINE
#endif
#define USE_COMPUTED_GOTOS 0
#endif
+#define INSTRUCTION_START() frame->f_lasti = INSTR_OFFSET(); next_instr++
+
#if USE_COMPUTED_GOTOS
-#define TARGET(op) TARGET_##op
+#define TARGET(op) TARGET_##op: INSTRUCTION_START();
#define DISPATCH_GOTO() goto *opcode_targets[opcode]
#else
-#define TARGET(op) case op
+#define TARGET(op) case op: INSTRUCTION_START();
#define DISPATCH_GOTO() goto dispatch_opcode
#endif
#endif
#endif
#ifndef PRE_DISPATCH_GOTO
-#define PRE_DISPATCH_GOTO() do { LLTRACE_INSTR(); RECORD_DXPROFILE(); } while (0)
+#define PRE_DISPATCH_GOTO() do { LLTRACE_INSTR(); RECORD_DXPROFILE(); } while (0)
#endif
#define NOTRACE_DISPATCH() \
{ \
- frame->f_lasti = INSTR_OFFSET(); \
NEXTOPARG(); \
PRE_DISPATCH_GOTO(); \
DISPATCH_GOTO(); \
/* Do interpreter dispatch accounting for tracing and instrumentation */
#define DISPATCH() \
{ \
- if (cframe.use_tracing OR_DTRACE_LINE) { \
- goto tracing_dispatch; \
- } \
- NOTRACE_DISPATCH(); \
+ NEXTOPARG(); \
+ PRE_DISPATCH_GOTO(); \
+ assert(cframe.use_tracing == 0 || cframe.use_tracing == 255); \
+ opcode |= cframe.use_tracing OR_DTRACE_LINE; \
+ DISPATCH_GOTO(); \
}
#define CHECK_EVAL_BREAKER() \
_Py_CODEUNIT word = *next_instr; \
opcode = _Py_OPCODE(word); \
oparg = _Py_OPARG(word); \
- next_instr++; \
} while (0)
#define JUMPTO(x) (next_instr = first_instr + (x))
#define JUMPBY(x) (next_instr += (x))
_Py_CODEUNIT word = ((_Py_CODEUNIT *)PyBytes_AS_STRING(co->co_code))[INSTR_OFFSET()]; \
opcode = _Py_OPCODE(word); \
oparg = _Py_OPARG(word); \
- next_instr++; \
} while (0)
/* OpCode prediction macros
#define PREDICT(op) \
do { \
_Py_CODEUNIT word = *next_instr; \
- opcode = _Py_OPCODE(word); \
+ opcode = _Py_OPCODE(word) | cframe.use_tracing OR_DTRACE_LINE; \
if (opcode == op) { \
oparg = _Py_OPARG(word); \
- next_instr++; \
+ INSTRUCTION_START(); \
goto PREDICT_ID(op); \
} \
} while(0)
return 0;
}
+static int
+skip_backwards_over_extended_args(PyCodeObject *code, int offset) {
+ _Py_CODEUNIT *instrs = (_Py_CODEUNIT *)PyBytes_AS_STRING(code->co_code);
+ while (offset > 0 && _Py_OPCODE(instrs[offset-1]) == EXTENDED_ARG) {
+ offset--;
+ }
+ return offset;
+}
+
PyObject* _Py_HOT_FUNCTION
_PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int throwflag)
{
DISPATCH();
- tracing_dispatch:
- {
- int instr_prev = frame->f_lasti;
- frame->f_lasti = INSTR_OFFSET();
- TRACING_NEXTOPARG();
-
- if (PyDTrace_LINE_ENABLED())
- maybe_dtrace_line(frame, &tstate->trace_info, instr_prev);
-
- /* line-by-line tracing support */
-
- if (cframe.use_tracing &&
- tstate->c_tracefunc != NULL && !tstate->tracing) {
- int err;
- /* see maybe_call_line_trace()
- for expository comments */
- _PyFrame_SetStackPointer(frame, stack_pointer);
-
- err = maybe_call_line_trace(tstate->c_tracefunc,
- tstate->c_traceobj,
- tstate, frame, instr_prev);
- if (err) {
- /* trace function raised an exception */
- goto error;
- }
- /* Reload possibly changed frame fields */
- JUMPTO(frame->f_lasti);
-
- stack_pointer = _PyFrame_GetStackPointer(frame);
- frame->stacktop = -1;
- TRACING_NEXTOPARG();
- }
- PRE_DISPATCH_GOTO();
- DISPATCH_GOTO();
- }
-
/* Start instructions */
#if USE_COMPUTED_GOTOS
{
It is essential that any operation that fails must goto error
and that all operation that succeed call DISPATCH() ! */
- TARGET(NOP): {
+ TARGET(NOP) {
DISPATCH();
}
/* We keep LOAD_CLOSURE so that the bytecode stays more readable. */
- TARGET(LOAD_CLOSURE):
- TARGET(LOAD_FAST): {
+ TARGET(LOAD_CLOSURE) {
PyObject *value = GETLOCAL(oparg);
if (value == NULL) {
goto unbound_local_error;
DISPATCH();
}
- TARGET(LOAD_CONST): {
+ TARGET(LOAD_FAST) {
+ PyObject *value = GETLOCAL(oparg);
+ if (value == NULL) {
+ goto unbound_local_error;
+ }
+ Py_INCREF(value);
+ PUSH(value);
+ DISPATCH();
+ }
+
+ TARGET(LOAD_CONST) {
PREDICTED(LOAD_CONST);
PyObject *value = GETITEM(consts, oparg);
Py_INCREF(value);
DISPATCH();
}
- TARGET(STORE_FAST): {
+ TARGET(STORE_FAST) {
PREDICTED(STORE_FAST);
PyObject *value = POP();
SETLOCAL(oparg, value);
DISPATCH();
}
- TARGET(LOAD_FAST__LOAD_FAST): {
+ TARGET(LOAD_FAST__LOAD_FAST) {
PyObject *value = GETLOCAL(oparg);
if (value == NULL) {
goto unbound_local_error;
}
NEXTOPARG();
+ next_instr++;
Py_INCREF(value);
PUSH(value);
value = GETLOCAL(oparg);
NOTRACE_DISPATCH();
}
- TARGET(LOAD_FAST__LOAD_CONST): {
+ TARGET(LOAD_FAST__LOAD_CONST) {
PyObject *value = GETLOCAL(oparg);
if (value == NULL) {
goto unbound_local_error;
}
NEXTOPARG();
+ next_instr++;
Py_INCREF(value);
PUSH(value);
value = GETITEM(consts, oparg);
NOTRACE_DISPATCH();
}
- TARGET(STORE_FAST__LOAD_FAST): {
+ TARGET(STORE_FAST__LOAD_FAST) {
PyObject *value = POP();
SETLOCAL(oparg, value);
NEXTOPARG();
+ next_instr++;
value = GETLOCAL(oparg);
if (value == NULL) {
goto unbound_local_error;
NOTRACE_DISPATCH();
}
- TARGET(STORE_FAST__STORE_FAST): {
+ TARGET(STORE_FAST__STORE_FAST) {
PyObject *value = POP();
SETLOCAL(oparg, value);
NEXTOPARG();
+ next_instr++;
value = POP();
SETLOCAL(oparg, value);
NOTRACE_DISPATCH();
}
- TARGET(LOAD_CONST__LOAD_FAST): {
+ TARGET(LOAD_CONST__LOAD_FAST) {
PyObject *value = GETITEM(consts, oparg);
NEXTOPARG();
+ next_instr++;
Py_INCREF(value);
PUSH(value);
value = GETLOCAL(oparg);
NOTRACE_DISPATCH();
}
- TARGET(POP_TOP): {
+ TARGET(POP_TOP) {
PyObject *value = POP();
Py_DECREF(value);
DISPATCH();
}
- TARGET(ROT_TWO): {
+ TARGET(ROT_TWO) {
PyObject *top = TOP();
PyObject *second = SECOND();
SET_TOP(second);
DISPATCH();
}
- TARGET(ROT_THREE): {
+ TARGET(ROT_THREE) {
PyObject *top = TOP();
PyObject *second = SECOND();
PyObject *third = THIRD();
DISPATCH();
}
- TARGET(ROT_FOUR): {
+ TARGET(ROT_FOUR) {
PyObject *top = TOP();
PyObject *second = SECOND();
PyObject *third = THIRD();
DISPATCH();
}
- TARGET(DUP_TOP): {
+ TARGET(DUP_TOP) {
PyObject *top = TOP();
Py_INCREF(top);
PUSH(top);
DISPATCH();
}
- TARGET(DUP_TOP_TWO): {
+ TARGET(DUP_TOP_TWO) {
PyObject *top = TOP();
PyObject *second = SECOND();
Py_INCREF(top);
DISPATCH();
}
- TARGET(UNARY_POSITIVE): {
+ TARGET(UNARY_POSITIVE) {
PyObject *value = TOP();
PyObject *res = PyNumber_Positive(value);
Py_DECREF(value);
DISPATCH();
}
- TARGET(UNARY_NEGATIVE): {
+ TARGET(UNARY_NEGATIVE) {
PyObject *value = TOP();
PyObject *res = PyNumber_Negative(value);
Py_DECREF(value);
DISPATCH();
}
- TARGET(UNARY_NOT): {
+ TARGET(UNARY_NOT) {
PyObject *value = TOP();
int err = PyObject_IsTrue(value);
Py_DECREF(value);
goto error;
}
- TARGET(UNARY_INVERT): {
+ TARGET(UNARY_INVERT) {
PyObject *value = TOP();
PyObject *res = PyNumber_Invert(value);
Py_DECREF(value);
DISPATCH();
}
- TARGET(BINARY_POWER): {
+ TARGET(BINARY_POWER) {
PyObject *exp = POP();
PyObject *base = TOP();
PyObject *res = PyNumber_Power(base, exp, Py_None);
DISPATCH();
}
- TARGET(BINARY_MULTIPLY): {
+ TARGET(BINARY_MULTIPLY) {
PyObject *right = POP();
PyObject *left = TOP();
PyObject *res = PyNumber_Multiply(left, right);
DISPATCH();
}
- TARGET(BINARY_MATRIX_MULTIPLY): {
+ TARGET(BINARY_MATRIX_MULTIPLY) {
PyObject *right = POP();
PyObject *left = TOP();
PyObject *res = PyNumber_MatrixMultiply(left, right);
DISPATCH();
}
- TARGET(BINARY_TRUE_DIVIDE): {
+ TARGET(BINARY_TRUE_DIVIDE) {
PyObject *divisor = POP();
PyObject *dividend = TOP();
PyObject *quotient = PyNumber_TrueDivide(dividend, divisor);
DISPATCH();
}
- TARGET(BINARY_FLOOR_DIVIDE): {
+ TARGET(BINARY_FLOOR_DIVIDE) {
PyObject *divisor = POP();
PyObject *dividend = TOP();
PyObject *quotient = PyNumber_FloorDivide(dividend, divisor);
DISPATCH();
}
- TARGET(BINARY_MODULO): {
+ TARGET(BINARY_MODULO) {
PyObject *divisor = POP();
PyObject *dividend = TOP();
PyObject *res;
DISPATCH();
}
- TARGET(BINARY_ADD): {
+ TARGET(BINARY_ADD) {
PREDICTED(BINARY_ADD);
STAT_INC(BINARY_ADD, unquickened);
PyObject *right = POP();
DISPATCH();
}
- TARGET(BINARY_ADD_ADAPTIVE): {
+ TARGET(BINARY_ADD_ADAPTIVE) {
if (oparg == 0) {
PyObject *left = SECOND();
PyObject *right = TOP();
}
}
- TARGET(BINARY_ADD_UNICODE): {
+ TARGET(BINARY_ADD_UNICODE) {
PyObject *left = SECOND();
PyObject *right = TOP();
DEOPT_IF(!PyUnicode_CheckExact(left), BINARY_ADD);
DISPATCH();
}
- TARGET(BINARY_ADD_UNICODE_INPLACE_FAST): {
+ TARGET(BINARY_ADD_UNICODE_INPLACE_FAST) {
PyObject *left = SECOND();
PyObject *right = TOP();
DEOPT_IF(!PyUnicode_CheckExact(left), BINARY_ADD);
DISPATCH();
}
- TARGET(BINARY_ADD_FLOAT): {
+ TARGET(BINARY_ADD_FLOAT) {
PyObject *left = SECOND();
PyObject *right = TOP();
DEOPT_IF(!PyFloat_CheckExact(left), BINARY_ADD);
DISPATCH();
}
- TARGET(BINARY_ADD_INT): {
+ TARGET(BINARY_ADD_INT) {
PyObject *left = SECOND();
PyObject *right = TOP();
DEOPT_IF(!PyLong_CheckExact(left), BINARY_ADD);
DISPATCH();
}
- TARGET(BINARY_SUBTRACT): {
+ TARGET(BINARY_SUBTRACT) {
PyObject *right = POP();
PyObject *left = TOP();
PyObject *diff = PyNumber_Subtract(left, right);
DISPATCH();
}
- TARGET(BINARY_SUBSCR): {
+ TARGET(BINARY_SUBSCR) {
PREDICTED(BINARY_SUBSCR);
STAT_INC(BINARY_SUBSCR, unquickened);
PyObject *sub = POP();
DISPATCH();
}
- TARGET(BINARY_SUBSCR_ADAPTIVE): {
+ TARGET(BINARY_SUBSCR_ADAPTIVE) {
if (oparg == 0) {
PyObject *sub = TOP();
PyObject *container = SECOND();
}
}
- TARGET(BINARY_SUBSCR_LIST_INT): {
+ TARGET(BINARY_SUBSCR_LIST_INT) {
PyObject *sub = TOP();
PyObject *list = SECOND();
DEOPT_IF(!PyLong_CheckExact(sub), BINARY_SUBSCR);
DISPATCH();
}
- TARGET(BINARY_SUBSCR_TUPLE_INT): {
+ TARGET(BINARY_SUBSCR_TUPLE_INT) {
PyObject *sub = TOP();
PyObject *tuple = SECOND();
DEOPT_IF(!PyLong_CheckExact(sub), BINARY_SUBSCR);
DISPATCH();
}
- TARGET(BINARY_SUBSCR_DICT): {
+ TARGET(BINARY_SUBSCR_DICT) {
PyObject *dict = SECOND();
DEOPT_IF(!PyDict_CheckExact(SECOND()), BINARY_SUBSCR);
STAT_INC(BINARY_SUBSCR, hit);
DISPATCH();
}
- TARGET(BINARY_LSHIFT): {
+ TARGET(BINARY_LSHIFT) {
PyObject *right = POP();
PyObject *left = TOP();
PyObject *res = PyNumber_Lshift(left, right);
DISPATCH();
}
- TARGET(BINARY_RSHIFT): {
+ TARGET(BINARY_RSHIFT) {
PyObject *right = POP();
PyObject *left = TOP();
PyObject *res = PyNumber_Rshift(left, right);
DISPATCH();
}
- TARGET(BINARY_AND): {
+ TARGET(BINARY_AND) {
PyObject *right = POP();
PyObject *left = TOP();
PyObject *res = PyNumber_And(left, right);
DISPATCH();
}
- TARGET(BINARY_XOR): {
+ TARGET(BINARY_XOR) {
PyObject *right = POP();
PyObject *left = TOP();
PyObject *res = PyNumber_Xor(left, right);
DISPATCH();
}
- TARGET(BINARY_OR): {
+ TARGET(BINARY_OR) {
PyObject *right = POP();
PyObject *left = TOP();
PyObject *res = PyNumber_Or(left, right);
DISPATCH();
}
- TARGET(LIST_APPEND): {
+ TARGET(LIST_APPEND) {
PyObject *v = POP();
PyObject *list = PEEK(oparg);
int err;
DISPATCH();
}
- TARGET(SET_ADD): {
+ TARGET(SET_ADD) {
PyObject *v = POP();
PyObject *set = PEEK(oparg);
int err;
DISPATCH();
}
- TARGET(INPLACE_POWER): {
+ TARGET(INPLACE_POWER) {
PyObject *exp = POP();
PyObject *base = TOP();
PyObject *res = PyNumber_InPlacePower(base, exp, Py_None);
DISPATCH();
}
- TARGET(INPLACE_MULTIPLY): {
+ TARGET(INPLACE_MULTIPLY) {
PyObject *right = POP();
PyObject *left = TOP();
PyObject *res = PyNumber_InPlaceMultiply(left, right);
DISPATCH();
}
- TARGET(INPLACE_MATRIX_MULTIPLY): {
+ TARGET(INPLACE_MATRIX_MULTIPLY) {
PyObject *right = POP();
PyObject *left = TOP();
PyObject *res = PyNumber_InPlaceMatrixMultiply(left, right);
DISPATCH();
}
- TARGET(INPLACE_TRUE_DIVIDE): {
+ TARGET(INPLACE_TRUE_DIVIDE) {
PyObject *divisor = POP();
PyObject *dividend = TOP();
PyObject *quotient = PyNumber_InPlaceTrueDivide(dividend, divisor);
DISPATCH();
}
- TARGET(INPLACE_FLOOR_DIVIDE): {
+ TARGET(INPLACE_FLOOR_DIVIDE) {
PyObject *divisor = POP();
PyObject *dividend = TOP();
PyObject *quotient = PyNumber_InPlaceFloorDivide(dividend, divisor);
DISPATCH();
}
- TARGET(INPLACE_MODULO): {
+ TARGET(INPLACE_MODULO) {
PyObject *right = POP();
PyObject *left = TOP();
PyObject *mod = PyNumber_InPlaceRemainder(left, right);
DISPATCH();
}
- TARGET(INPLACE_ADD): {
+ TARGET(INPLACE_ADD) {
PyObject *right = POP();
PyObject *left = TOP();
PyObject *sum;
DISPATCH();
}
- TARGET(INPLACE_SUBTRACT): {
+ TARGET(INPLACE_SUBTRACT) {
PyObject *right = POP();
PyObject *left = TOP();
PyObject *diff = PyNumber_InPlaceSubtract(left, right);
DISPATCH();
}
- TARGET(INPLACE_LSHIFT): {
+ TARGET(INPLACE_LSHIFT) {
PyObject *right = POP();
PyObject *left = TOP();
PyObject *res = PyNumber_InPlaceLshift(left, right);
DISPATCH();
}
- TARGET(INPLACE_RSHIFT): {
+ TARGET(INPLACE_RSHIFT) {
PyObject *right = POP();
PyObject *left = TOP();
PyObject *res = PyNumber_InPlaceRshift(left, right);
DISPATCH();
}
- TARGET(INPLACE_AND): {
+ TARGET(INPLACE_AND) {
PyObject *right = POP();
PyObject *left = TOP();
PyObject *res = PyNumber_InPlaceAnd(left, right);
DISPATCH();
}
- TARGET(INPLACE_XOR): {
+ TARGET(INPLACE_XOR) {
PyObject *right = POP();
PyObject *left = TOP();
PyObject *res = PyNumber_InPlaceXor(left, right);
DISPATCH();
}
- TARGET(INPLACE_OR): {
+ TARGET(INPLACE_OR) {
PyObject *right = POP();
PyObject *left = TOP();
PyObject *res = PyNumber_InPlaceOr(left, right);
DISPATCH();
}
- TARGET(STORE_SUBSCR): {
+ TARGET(STORE_SUBSCR) {
PyObject *sub = TOP();
PyObject *container = SECOND();
PyObject *v = THIRD();
DISPATCH();
}
- TARGET(DELETE_SUBSCR): {
+ TARGET(DELETE_SUBSCR) {
PyObject *sub = TOP();
PyObject *container = SECOND();
int err;
DISPATCH();
}
- TARGET(PRINT_EXPR): {
+ TARGET(PRINT_EXPR) {
_Py_IDENTIFIER(displayhook);
PyObject *value = POP();
PyObject *hook = _PySys_GetObjectId(&PyId_displayhook);
DISPATCH();
}
- TARGET(RAISE_VARARGS): {
+ TARGET(RAISE_VARARGS) {
PyObject *cause = NULL, *exc = NULL;
switch (oparg) {
case 2:
goto error;
}
- TARGET(RETURN_VALUE): {
+ TARGET(RETURN_VALUE) {
retval = POP();
assert(EMPTY());
frame->f_state = FRAME_RETURNED;
goto exiting;
}
- TARGET(GET_AITER): {
+ TARGET(GET_AITER) {
unaryfunc getter = NULL;
PyObject *iter = NULL;
PyObject *obj = TOP();
DISPATCH();
}
- TARGET(GET_ANEXT): {
+ TARGET(GET_ANEXT) {
unaryfunc getter = NULL;
PyObject *next_iter = NULL;
PyObject *awaitable = NULL;
DISPATCH();
}
- TARGET(GET_AWAITABLE): {
+ TARGET(GET_AWAITABLE) {
PREDICTED(GET_AWAITABLE);
PyObject *iterable = TOP();
PyObject *iter = _PyCoro_GetAwaitableIter(iterable);
DISPATCH();
}
- TARGET(YIELD_FROM): {
+ TARGET(YIELD_FROM) {
PyObject *v = POP();
PyObject *receiver = TOP();
PySendResult gen_status;
goto exiting;
}
- TARGET(YIELD_VALUE): {
+ TARGET(YIELD_VALUE) {
retval = POP();
if (co->co_flags & CO_ASYNC_GENERATOR) {
goto exiting;
}
- TARGET(GEN_START): {
+ TARGET(GEN_START) {
PyObject *none = POP();
Py_DECREF(none);
if (!Py_IsNone(none)) {
DISPATCH();
}
- TARGET(POP_EXCEPT): {
+ TARGET(POP_EXCEPT) {
PyObject *type, *value, *traceback;
_PyErr_StackItem *exc_info;
exc_info = tstate->exc_info;
DISPATCH();
}
- TARGET(POP_EXCEPT_AND_RERAISE): {
+ TARGET(POP_EXCEPT_AND_RERAISE) {
PyObject *lasti = PEEK(4);
if (PyLong_Check(lasti)) {
frame->f_lasti = PyLong_AsLong(lasti);
goto exception_unwind;
}
- TARGET(RERAISE): {
+ TARGET(RERAISE) {
if (oparg) {
PyObject *lasti = PEEK(oparg+3);
if (PyLong_Check(lasti)) {
goto exception_unwind;
}
- TARGET(END_ASYNC_FOR): {
+ TARGET(END_ASYNC_FOR) {
PyObject *exc = POP();
PyObject *val = POP();
PyObject *tb = POP();
}
}
- TARGET(LOAD_ASSERTION_ERROR): {
+ TARGET(LOAD_ASSERTION_ERROR) {
PyObject *value = PyExc_AssertionError;
Py_INCREF(value);
PUSH(value);
DISPATCH();
}
- TARGET(LOAD_BUILD_CLASS): {
+ TARGET(LOAD_BUILD_CLASS) {
_Py_IDENTIFIER(__build_class__);
PyObject *bc;
DISPATCH();
}
- TARGET(STORE_NAME): {
+ TARGET(STORE_NAME) {
PyObject *name = GETITEM(names, oparg);
PyObject *v = POP();
PyObject *ns = LOCALS();
DISPATCH();
}
- TARGET(DELETE_NAME): {
+ TARGET(DELETE_NAME) {
PyObject *name = GETITEM(names, oparg);
PyObject *ns = LOCALS();
int err;
DISPATCH();
}
- TARGET(UNPACK_SEQUENCE): {
+ TARGET(UNPACK_SEQUENCE) {
PREDICTED(UNPACK_SEQUENCE);
PyObject *seq = POP(), *item, **items;
if (PyTuple_CheckExact(seq) &&
DISPATCH();
}
- TARGET(UNPACK_EX): {
+ TARGET(UNPACK_EX) {
int totalargs = 1 + (oparg & 0xFF) + (oparg >> 8);
PyObject *seq = POP();
DISPATCH();
}
- TARGET(STORE_ATTR): {
+ TARGET(STORE_ATTR) {
PREDICTED(STORE_ATTR);
STAT_INC(STORE_ATTR, unquickened);
PyObject *name = GETITEM(names, oparg);
DISPATCH();
}
- TARGET(DELETE_ATTR): {
+ TARGET(DELETE_ATTR) {
PyObject *name = GETITEM(names, oparg);
PyObject *owner = POP();
int err;
DISPATCH();
}
- TARGET(STORE_GLOBAL): {
+ TARGET(STORE_GLOBAL) {
PyObject *name = GETITEM(names, oparg);
PyObject *v = POP();
int err;
DISPATCH();
}
- TARGET(DELETE_GLOBAL): {
+ TARGET(DELETE_GLOBAL) {
PyObject *name = GETITEM(names, oparg);
int err;
err = PyDict_DelItem(GLOBALS(), name);
DISPATCH();
}
- TARGET(LOAD_NAME): {
+ TARGET(LOAD_NAME) {
PyObject *name = GETITEM(names, oparg);
PyObject *locals = LOCALS();
PyObject *v;
DISPATCH();
}
- TARGET(LOAD_GLOBAL): {
+ TARGET(LOAD_GLOBAL) {
PREDICTED(LOAD_GLOBAL);
STAT_INC(LOAD_GLOBAL, unquickened);
PyObject *name = GETITEM(names, oparg);
DISPATCH();
}
- TARGET(LOAD_GLOBAL_ADAPTIVE): {
+ TARGET(LOAD_GLOBAL_ADAPTIVE) {
assert(cframe.use_tracing == 0);
SpecializedCacheEntry *cache = GET_CACHE();
if (cache->adaptive.counter == 0) {
}
}
- TARGET(LOAD_GLOBAL_MODULE): {
+ TARGET(LOAD_GLOBAL_MODULE) {
assert(cframe.use_tracing == 0);
DEOPT_IF(!PyDict_CheckExact(GLOBALS()), LOAD_GLOBAL);
PyDictObject *dict = (PyDictObject *)GLOBALS();
DISPATCH();
}
- TARGET(LOAD_GLOBAL_BUILTIN): {
+ TARGET(LOAD_GLOBAL_BUILTIN) {
assert(cframe.use_tracing == 0);
DEOPT_IF(!PyDict_CheckExact(GLOBALS()), LOAD_GLOBAL);
DEOPT_IF(!PyDict_CheckExact(BUILTINS()), LOAD_GLOBAL);
DISPATCH();
}
- TARGET(DELETE_FAST): {
+ TARGET(DELETE_FAST) {
PyObject *v = GETLOCAL(oparg);
if (v != NULL) {
SETLOCAL(oparg, NULL);
goto error;
}
- TARGET(MAKE_CELL): {
+ TARGET(MAKE_CELL) {
// "initial" is probably NULL but not if it's an arg (or set
// via PyFrame_LocalsToFast() before MAKE_CELL has run).
PyObject *initial = GETLOCAL(oparg);
DISPATCH();
}
- TARGET(DELETE_DEREF): {
+ TARGET(DELETE_DEREF) {
PyObject *cell = GETLOCAL(oparg);
PyObject *oldobj = PyCell_GET(cell);
if (oldobj != NULL) {
goto error;
}
- TARGET(LOAD_CLASSDEREF): {
+ TARGET(LOAD_CLASSDEREF) {
PyObject *name, *value, *locals = LOCALS();
assert(locals);
assert(oparg >= 0 && oparg < co->co_nlocalsplus);
DISPATCH();
}
- TARGET(LOAD_DEREF): {
+ TARGET(LOAD_DEREF) {
PyObject *cell = GETLOCAL(oparg);
PyObject *value = PyCell_GET(cell);
if (value == NULL) {
DISPATCH();
}
- TARGET(STORE_DEREF): {
+ TARGET(STORE_DEREF) {
PyObject *v = POP();
PyObject *cell = GETLOCAL(oparg);
PyObject *oldobj = PyCell_GET(cell);
DISPATCH();
}
- TARGET(BUILD_STRING): {
+ TARGET(BUILD_STRING) {
PyObject *str;
PyObject *empty = PyUnicode_New(0, 0);
if (empty == NULL) {
DISPATCH();
}
- TARGET(BUILD_TUPLE): {
+ TARGET(BUILD_TUPLE) {
PyObject *tup = PyTuple_New(oparg);
if (tup == NULL)
goto error;
DISPATCH();
}
- TARGET(BUILD_LIST): {
+ TARGET(BUILD_LIST) {
PyObject *list = PyList_New(oparg);
if (list == NULL)
goto error;
DISPATCH();
}
- TARGET(LIST_TO_TUPLE): {
+ TARGET(LIST_TO_TUPLE) {
PyObject *list = POP();
PyObject *tuple = PyList_AsTuple(list);
Py_DECREF(list);
DISPATCH();
}
- TARGET(LIST_EXTEND): {
+ TARGET(LIST_EXTEND) {
PyObject *iterable = POP();
PyObject *list = PEEK(oparg);
PyObject *none_val = _PyList_Extend((PyListObject *)list, iterable);
DISPATCH();
}
- TARGET(SET_UPDATE): {
+ TARGET(SET_UPDATE) {
PyObject *iterable = POP();
PyObject *set = PEEK(oparg);
int err = _PySet_Update(set, iterable);
DISPATCH();
}
- TARGET(BUILD_SET): {
+ TARGET(BUILD_SET) {
PyObject *set = PySet_New(NULL);
int err = 0;
int i;
DISPATCH();
}
- TARGET(BUILD_MAP): {
+ TARGET(BUILD_MAP) {
Py_ssize_t i;
PyObject *map = _PyDict_NewPresized((Py_ssize_t)oparg);
if (map == NULL)
DISPATCH();
}
- TARGET(SETUP_ANNOTATIONS): {
+ TARGET(SETUP_ANNOTATIONS) {
_Py_IDENTIFIER(__annotations__);
int err;
PyObject *ann_dict;
DISPATCH();
}
- TARGET(BUILD_CONST_KEY_MAP): {
+ TARGET(BUILD_CONST_KEY_MAP) {
Py_ssize_t i;
PyObject *map;
PyObject *keys = TOP();
DISPATCH();
}
- TARGET(DICT_UPDATE): {
+ TARGET(DICT_UPDATE) {
PyObject *update = POP();
PyObject *dict = PEEK(oparg);
if (PyDict_Update(dict, update) < 0) {
DISPATCH();
}
- TARGET(DICT_MERGE): {
+ TARGET(DICT_MERGE) {
PyObject *update = POP();
PyObject *dict = PEEK(oparg);
DISPATCH();
}
- TARGET(MAP_ADD): {
+ TARGET(MAP_ADD) {
PyObject *value = TOP();
PyObject *key = SECOND();
PyObject *map;
DISPATCH();
}
- TARGET(LOAD_ATTR): {
+ TARGET(LOAD_ATTR) {
PREDICTED(LOAD_ATTR);
STAT_INC(LOAD_ATTR, unquickened);
PyObject *name = GETITEM(names, oparg);
DISPATCH();
}
- TARGET(LOAD_ATTR_ADAPTIVE): {
+ TARGET(LOAD_ATTR_ADAPTIVE) {
assert(cframe.use_tracing == 0);
SpecializedCacheEntry *cache = GET_CACHE();
if (cache->adaptive.counter == 0) {
}
}
- TARGET(LOAD_ATTR_SPLIT_KEYS): {
+ TARGET(LOAD_ATTR_SPLIT_KEYS) {
assert(cframe.use_tracing == 0);
PyObject *owner = TOP();
PyObject *res;
DISPATCH();
}
- TARGET(LOAD_ATTR_MODULE): {
+ TARGET(LOAD_ATTR_MODULE) {
assert(cframe.use_tracing == 0);
// shared with LOAD_METHOD_MODULE
PyObject *owner = TOP();
DISPATCH();
}
- TARGET(LOAD_ATTR_WITH_HINT): {
+ TARGET(LOAD_ATTR_WITH_HINT) {
assert(cframe.use_tracing == 0);
PyObject *owner = TOP();
PyObject *res;
DISPATCH();
}
- TARGET(LOAD_ATTR_SLOT): {
+ TARGET(LOAD_ATTR_SLOT) {
assert(cframe.use_tracing == 0);
PyObject *owner = TOP();
PyObject *res;
DISPATCH();
}
- TARGET(STORE_ATTR_ADAPTIVE): {
+ TARGET(STORE_ATTR_ADAPTIVE) {
assert(cframe.use_tracing == 0);
SpecializedCacheEntry *cache = GET_CACHE();
if (cache->adaptive.counter == 0) {
}
}
- TARGET(STORE_ATTR_SPLIT_KEYS): {
+ TARGET(STORE_ATTR_SPLIT_KEYS) {
assert(cframe.use_tracing == 0);
PyObject *owner = TOP();
PyTypeObject *tp = Py_TYPE(owner);
DISPATCH();
}
- TARGET(STORE_ATTR_WITH_HINT): {
+ TARGET(STORE_ATTR_WITH_HINT) {
assert(cframe.use_tracing == 0);
PyObject *owner = TOP();
PyTypeObject *tp = Py_TYPE(owner);
DISPATCH();
}
- TARGET(STORE_ATTR_SLOT): {
+ TARGET(STORE_ATTR_SLOT) {
assert(cframe.use_tracing == 0);
PyObject *owner = TOP();
PyTypeObject *tp = Py_TYPE(owner);
DISPATCH();
}
- TARGET(COMPARE_OP): {
+ TARGET(COMPARE_OP) {
assert(oparg <= Py_GE);
PyObject *right = POP();
PyObject *left = TOP();
DISPATCH();
}
- TARGET(IS_OP): {
+ TARGET(IS_OP) {
PyObject *right = POP();
PyObject *left = TOP();
int res = Py_Is(left, right) ^ oparg;
DISPATCH();
}
- TARGET(CONTAINS_OP): {
+ TARGET(CONTAINS_OP) {
PyObject *right = POP();
PyObject *left = POP();
int res = PySequence_Contains(right, left);
#define CANNOT_CATCH_MSG "catching classes that do not inherit from "\
"BaseException is not allowed"
- TARGET(JUMP_IF_NOT_EXC_MATCH): {
+ TARGET(JUMP_IF_NOT_EXC_MATCH) {
PyObject *right = POP();
PyObject *left = POP();
if (PyTuple_Check(right)) {
DISPATCH();
}
- TARGET(IMPORT_NAME): {
+ TARGET(IMPORT_NAME) {
PyObject *name = GETITEM(names, oparg);
PyObject *fromlist = POP();
PyObject *level = TOP();
DISPATCH();
}
- TARGET(IMPORT_STAR): {
+ TARGET(IMPORT_STAR) {
PyObject *from = POP(), *locals;
int err;
if (_PyFrame_FastToLocalsWithError(frame) < 0) {
DISPATCH();
}
- TARGET(IMPORT_FROM): {
+ TARGET(IMPORT_FROM) {
PyObject *name = GETITEM(names, oparg);
PyObject *from = TOP();
PyObject *res;
DISPATCH();
}
- TARGET(JUMP_FORWARD): {
+ TARGET(JUMP_FORWARD) {
JUMPBY(oparg);
DISPATCH();
}
- TARGET(POP_JUMP_IF_FALSE): {
+ TARGET(POP_JUMP_IF_FALSE) {
PREDICTED(POP_JUMP_IF_FALSE);
PyObject *cond = POP();
int err;
DISPATCH();
}
- TARGET(POP_JUMP_IF_TRUE): {
+ TARGET(POP_JUMP_IF_TRUE) {
PREDICTED(POP_JUMP_IF_TRUE);
PyObject *cond = POP();
int err;
DISPATCH();
}
- TARGET(JUMP_IF_FALSE_OR_POP): {
+ TARGET(JUMP_IF_FALSE_OR_POP) {
PyObject *cond = TOP();
int err;
if (Py_IsTrue(cond)) {
DISPATCH();
}
- TARGET(JUMP_IF_TRUE_OR_POP): {
+ TARGET(JUMP_IF_TRUE_OR_POP) {
PyObject *cond = TOP();
int err;
if (Py_IsFalse(cond)) {
DISPATCH();
}
- TARGET(JUMP_ABSOLUTE): {
+ TARGET(JUMP_ABSOLUTE) {
PREDICTED(JUMP_ABSOLUTE);
if (oparg < INSTR_OFFSET()) {
/* Increment the warmup counter and quicken if warm enough
DISPATCH();
}
- TARGET(JUMP_ABSOLUTE_QUICK): {
+ TARGET(JUMP_ABSOLUTE_QUICK) {
JUMPTO(oparg);
CHECK_EVAL_BREAKER();
DISPATCH();
}
- TARGET(GET_LEN): {
+ TARGET(GET_LEN) {
// PUSH(len(TOS))
Py_ssize_t len_i = PyObject_Length(TOP());
if (len_i < 0) {
DISPATCH();
}
- TARGET(MATCH_CLASS): {
+ TARGET(MATCH_CLASS) {
// Pop TOS. On success, set TOS to True and TOS1 to a tuple of
// attributes. On failure, set TOS to False.
PyObject *names = POP();
DISPATCH();
}
- TARGET(MATCH_MAPPING): {
+ TARGET(MATCH_MAPPING) {
PyObject *subject = TOP();
int match = Py_TYPE(subject)->tp_flags & Py_TPFLAGS_MAPPING;
PyObject *res = match ? Py_True : Py_False;
DISPATCH();
}
- TARGET(MATCH_SEQUENCE): {
+ TARGET(MATCH_SEQUENCE) {
PyObject *subject = TOP();
int match = Py_TYPE(subject)->tp_flags & Py_TPFLAGS_SEQUENCE;
PyObject *res = match ? Py_True : Py_False;
DISPATCH();
}
- TARGET(MATCH_KEYS): {
+ TARGET(MATCH_KEYS) {
// On successful match for all keys, PUSH(values) and PUSH(True).
// Otherwise, PUSH(None) and PUSH(False).
PyObject *keys = TOP();
DISPATCH();
}
- TARGET(COPY_DICT_WITHOUT_KEYS): {
+ TARGET(COPY_DICT_WITHOUT_KEYS) {
// rest = dict(TOS1)
// for key in TOS:
// del rest[key]
DISPATCH();
}
- TARGET(GET_ITER): {
+ TARGET(GET_ITER) {
/* before: [obj]; after [getiter(obj)] */
PyObject *iterable = TOP();
PyObject *iter = PyObject_GetIter(iterable);
DISPATCH();
}
- TARGET(GET_YIELD_FROM_ITER): {
+ TARGET(GET_YIELD_FROM_ITER) {
/* before: [obj]; after [getiter(obj)] */
PyObject *iterable = TOP();
PyObject *iter;
DISPATCH();
}
- TARGET(FOR_ITER): {
+ TARGET(FOR_ITER) {
PREDICTED(FOR_ITER);
/* before: [iter]; after: [iter, iter()] *or* [] */
PyObject *iter = TOP();
DISPATCH();
}
- TARGET(BEFORE_ASYNC_WITH): {
+ TARGET(BEFORE_ASYNC_WITH) {
_Py_IDENTIFIER(__aenter__);
_Py_IDENTIFIER(__aexit__);
PyObject *mgr = TOP();
DISPATCH();
}
- TARGET(BEFORE_WITH): {
+ TARGET(BEFORE_WITH) {
_Py_IDENTIFIER(__enter__);
_Py_IDENTIFIER(__exit__);
PyObject *mgr = TOP();
DISPATCH();
}
- TARGET(WITH_EXCEPT_START): {
+ TARGET(WITH_EXCEPT_START) {
/* At the top of the stack are 8 values:
- (TOP, SECOND, THIRD) = exc_info()
- (FOURTH, FIFTH, SIXTH) = previous exception
DISPATCH();
}
- TARGET(PUSH_EXC_INFO): {
+ TARGET(PUSH_EXC_INFO) {
PyObject *type = TOP();
PyObject *value = SECOND();
PyObject *tb = THIRD();
DISPATCH();
}
- TARGET(LOAD_METHOD): {
+ TARGET(LOAD_METHOD) {
PREDICTED(LOAD_METHOD);
STAT_INC(LOAD_METHOD, unquickened);
/* Designed to work in tandem with CALL_METHOD. */
DISPATCH();
}
- TARGET(LOAD_METHOD_ADAPTIVE): {
+ TARGET(LOAD_METHOD_ADAPTIVE) {
assert(cframe.use_tracing == 0);
SpecializedCacheEntry *cache = GET_CACHE();
if (cache->adaptive.counter == 0) {
}
}
- TARGET(LOAD_METHOD_CACHED): {
+ TARGET(LOAD_METHOD_CACHED) {
/* LOAD_METHOD, with cached method object */
assert(cframe.use_tracing == 0);
PyObject *self = TOP();
DISPATCH();
}
- TARGET(LOAD_METHOD_MODULE): {
+ TARGET(LOAD_METHOD_MODULE) {
/* LOAD_METHOD, for module methods */
assert(cframe.use_tracing == 0);
PyObject *owner = TOP();
DISPATCH();
}
- TARGET(LOAD_METHOD_CLASS): {
+ TARGET(LOAD_METHOD_CLASS) {
/* LOAD_METHOD, for class methods */
assert(cframe.use_tracing == 0);
SpecializedCacheEntry *caches = GET_CACHE();
DISPATCH();
}
- TARGET(CALL_METHOD): {
+ TARGET(CALL_METHOD) {
/* Designed to work in tamdem with LOAD_METHOD. */
PyObject **sp, *res;
int meth_found;
DISPATCH();
}
- TARGET(CALL_METHOD_KW): {
+ TARGET(CALL_METHOD_KW) {
/* Designed to work in tandem with LOAD_METHOD. Same as CALL_METHOD
but pops TOS to get a tuple of keyword names. */
PyObject **sp, *res;
DISPATCH();
}
- TARGET(CALL_FUNCTION): {
+ TARGET(CALL_FUNCTION) {
PREDICTED(CALL_FUNCTION);
PyObject **sp, *res;
sp = stack_pointer;
DISPATCH();
}
- TARGET(CALL_FUNCTION_KW): {
+ TARGET(CALL_FUNCTION_KW) {
PyObject **sp, *res, *names;
names = POP();
DISPATCH();
}
- TARGET(CALL_FUNCTION_EX): {
+ TARGET(CALL_FUNCTION_EX) {
PREDICTED(CALL_FUNCTION_EX);
PyObject *func, *callargs, *kwargs = NULL, *result;
if (oparg & 0x01) {
DISPATCH();
}
- TARGET(MAKE_FUNCTION): {
+ TARGET(MAKE_FUNCTION) {
PyObject *codeobj = POP();
PyFunctionObject *func = (PyFunctionObject *)
PyFunction_New(codeobj, GLOBALS());
DISPATCH();
}
- TARGET(BUILD_SLICE): {
+ TARGET(BUILD_SLICE) {
PyObject *start, *stop, *step, *slice;
if (oparg == 3)
step = POP();
DISPATCH();
}
- TARGET(FORMAT_VALUE): {
+ TARGET(FORMAT_VALUE) {
/* Handles f-string value formatting. */
PyObject *result;
PyObject *fmt_spec;
DISPATCH();
}
- TARGET(ROT_N): {
+ TARGET(ROT_N) {
PyObject *top = TOP();
memmove(&PEEK(oparg - 1), &PEEK(oparg),
sizeof(PyObject*) * (oparg - 1));
DISPATCH();
}
- TARGET(EXTENDED_ARG): {
+ TARGET(EXTENDED_ARG) {
int oldoparg = oparg;
NEXTOPARG();
oparg |= oldoparg << 8;
DISPATCH_GOTO();
}
+#if USE_COMPUTED_GOTOS
+ TARGET_DO_TRACING: {
+#else
+ case DO_TRACING: {
+#endif
+ int instr_prev = skip_backwards_over_extended_args(co, frame->f_lasti);
+ frame->f_lasti = INSTR_OFFSET();
+ TRACING_NEXTOPARG();
+ if (PyDTrace_LINE_ENABLED()) {
+ maybe_dtrace_line(frame, &tstate->trace_info, instr_prev);
+ }
+ /* line-by-line tracing support */
+
+ if (cframe.use_tracing &&
+ tstate->c_tracefunc != NULL && !tstate->tracing) {
+ int err;
+ /* see maybe_call_line_trace()
+ for expository comments */
+ _PyFrame_SetStackPointer(frame, stack_pointer);
+
+ err = maybe_call_line_trace(tstate->c_tracefunc,
+ tstate->c_traceobj,
+ tstate, frame, instr_prev);
+ if (err) {
+ /* trace function raised an exception */
+ next_instr++;
+ goto error;
+ }
+ /* Reload possibly changed frame fields */
+ JUMPTO(frame->f_lasti);
+
+ stack_pointer = _PyFrame_GetStackPointer(frame);
+ frame->stacktop = -1;
+ TRACING_NEXTOPARG();
+ }
+ PRE_DISPATCH_GOTO();
+ DISPATCH_GOTO();
+ }
+
#if USE_COMPUTED_GOTOS
_unknown_opcode:
result = func(obj, f, what, arg);
f->f_lineno = 0;
tstate->cframe->use_tracing = ((tstate->c_tracefunc != NULL)
- || (tstate->c_profilefunc != NULL));
+ || (tstate->c_profilefunc != NULL)) ? 255 : 0;
tstate->tracing--;
return result;
}
tstate->tracing = 0;
tstate->cframe->use_tracing = ((tstate->c_tracefunc != NULL)
- || (tstate->c_profilefunc != NULL));
+ || (tstate->c_profilefunc != NULL)) ? 255 : 0;
result = PyObject_Call(func, args, NULL);
tstate->tracing = save_tracing;
tstate->cframe->use_tracing = save_use_tracing;
tstate->c_profilefunc = func;
/* Flag that tracing or profiling is turned on */
- tstate->cframe->use_tracing = (func != NULL) || (tstate->c_tracefunc != NULL);
+ tstate->cframe->use_tracing = (func != NULL) || (tstate->c_tracefunc != NULL) ? 255 : 0;
return 0;
}
tstate->c_tracefunc = NULL;
tstate->c_traceobj = NULL;
/* Must make sure that profiling is not ignored if 'traceobj' is freed */
- tstate->cframe->use_tracing = (tstate->c_profilefunc != NULL);
+ tstate->cframe->use_tracing = (tstate->c_profilefunc != NULL) ? 255 : 0;
Py_XDECREF(traceobj);
Py_XINCREF(arg);
/* Flag that tracing or profiling is turned on */
tstate->cframe->use_tracing = ((func != NULL)
- || (tstate->c_profilefunc != NULL));
+ || (tstate->c_profilefunc != NULL)) ? 255 : 0;
return 0;
}
*/
int opcode, oparg;
NEXTOPARG();
+ next_instr++;
switch (opcode) {
case STORE_FAST:
{