case CALL_LEN:
return 2 + oparg;
case CALL_LIST_APPEND:
- return 2 + oparg;
+ return 3;
case CALL_METHOD_DESCRIPTOR_FAST:
return 2 + oparg;
case CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS:
case CALL_PY_WITH_DEFAULTS:
return 2 + oparg;
case CALL_STR_1:
- return 2 + oparg;
+ return 3;
case CALL_TUPLE_1:
- return 2 + oparg;
+ return 3;
case CALL_TYPE_1:
- return 2 + oparg;
+ return 3;
case CHECK_EG_MATCH:
return 2;
case CHECK_EXC_MATCH:
case UNPACK_SEQUENCE_TUPLE:
return oparg;
case UNPACK_SEQUENCE_TWO_TUPLE:
- return oparg;
+ return 2;
case WITH_EXCEPT_START:
return 5;
case YIELD_VALUE:
PyObject *top;
PyObject *type;
PyObject *typevars;
+ PyObject *val0;
+ PyObject *val1;
int values_or_none;
switch (opcode) {
macro(UNPACK_SEQUENCE) = _SPECIALIZE_UNPACK_SEQUENCE + _UNPACK_SEQUENCE;
- inst(UNPACK_SEQUENCE_TWO_TUPLE, (unused/1, seq -- values[oparg])) {
+ inst(UNPACK_SEQUENCE_TWO_TUPLE, (unused/1, seq -- val1, val0)) {
+ assert(oparg == 2);
DEOPT_IF(!PyTuple_CheckExact(seq));
DEOPT_IF(PyTuple_GET_SIZE(seq) != 2);
- assert(oparg == 2);
STAT_INC(UNPACK_SEQUENCE, hit);
- values[0] = Py_NewRef(PyTuple_GET_ITEM(seq, 1));
- values[1] = Py_NewRef(PyTuple_GET_ITEM(seq, 0));
+ val0 = Py_NewRef(PyTuple_GET_ITEM(seq, 0));
+ val1 = Py_NewRef(PyTuple_GET_ITEM(seq, 1));
DECREF_INPUTS();
}
DISPATCH_INLINED(new_frame);
}
- inst(CALL_TYPE_1, (unused/1, unused/2, callable, null, args[oparg] -- res)) {
+ inst(CALL_TYPE_1, (unused/1, unused/2, callable, null, arg -- res)) {
assert(oparg == 1);
DEOPT_IF(null != NULL);
- PyObject *obj = args[0];
DEOPT_IF(callable != (PyObject *)&PyType_Type);
STAT_INC(CALL, hit);
- res = Py_NewRef(Py_TYPE(obj));
- Py_DECREF(obj);
- Py_DECREF(&PyType_Type); // I.e., callable
+ res = Py_NewRef(Py_TYPE(arg));
+ Py_DECREF(arg);
}
- inst(CALL_STR_1, (unused/1, unused/2, callable, null, args[oparg] -- res)) {
+ inst(CALL_STR_1, (unused/1, unused/2, callable, null, arg -- res)) {
assert(oparg == 1);
DEOPT_IF(null != NULL);
DEOPT_IF(callable != (PyObject *)&PyUnicode_Type);
STAT_INC(CALL, hit);
- PyObject *arg = args[0];
res = PyObject_Str(arg);
Py_DECREF(arg);
- Py_DECREF(&PyUnicode_Type); // I.e., callable
ERROR_IF(res == NULL, error);
CHECK_EVAL_BREAKER();
}
- inst(CALL_TUPLE_1, (unused/1, unused/2, callable, null, args[oparg] -- res)) {
+ inst(CALL_TUPLE_1, (unused/1, unused/2, callable, null, arg -- res)) {
assert(oparg == 1);
DEOPT_IF(null != NULL);
DEOPT_IF(callable != (PyObject *)&PyTuple_Type);
STAT_INC(CALL, hit);
- PyObject *arg = args[0];
res = PySequence_Tuple(arg);
Py_DECREF(arg);
- Py_DECREF(&PyTuple_Type); // I.e., tuple
ERROR_IF(res == NULL, error);
CHECK_EVAL_BREAKER();
}
}
// This is secretly a super-instruction
- tier1 inst(CALL_LIST_APPEND, (unused/1, unused/2, callable, self, args[oparg] -- unused)) {
+ tier1 inst(CALL_LIST_APPEND, (unused/1, unused/2, callable, self, arg -- unused)) {
assert(oparg == 1);
PyInterpreterState *interp = tstate->interp;
DEOPT_IF(callable != interp->callable_cache.list_append);
assert(self != NULL);
DEOPT_IF(!PyList_Check(self));
STAT_INC(CALL, hit);
- if (_PyList_AppendTakeRef((PyListObject *)self, args[0]) < 0) {
+ if (_PyList_AppendTakeRef((PyListObject *)self, arg) < 0) {
goto pop_1_error; // Since arg is DECREF'ed already
}
Py_DECREF(self);
case _UNPACK_SEQUENCE_TWO_TUPLE: {
PyObject *seq;
- PyObject **values;
+ PyObject *val1;
+ PyObject *val0;
oparg = CURRENT_OPARG();
seq = stack_pointer[-1];
- values = &stack_pointer[-1];
+ assert(oparg == 2);
if (!PyTuple_CheckExact(seq)) goto deoptimize;
if (PyTuple_GET_SIZE(seq) != 2) goto deoptimize;
- assert(oparg == 2);
STAT_INC(UNPACK_SEQUENCE, hit);
- values[0] = Py_NewRef(PyTuple_GET_ITEM(seq, 1));
- values[1] = Py_NewRef(PyTuple_GET_ITEM(seq, 0));
+ val0 = Py_NewRef(PyTuple_GET_ITEM(seq, 0));
+ val1 = Py_NewRef(PyTuple_GET_ITEM(seq, 1));
Py_DECREF(seq);
- stack_pointer += -1 + oparg;
+ stack_pointer[-1] = val1;
+ stack_pointer[0] = val0;
+ stack_pointer += 1;
break;
}
/* _CALL_PY_WITH_DEFAULTS is not a viable micro-op for tier 2 */
case _CALL_TYPE_1: {
- PyObject **args;
+ PyObject *arg;
PyObject *null;
PyObject *callable;
PyObject *res;
oparg = CURRENT_OPARG();
- args = &stack_pointer[-oparg];
- null = stack_pointer[-1 - oparg];
- callable = stack_pointer[-2 - oparg];
+ arg = stack_pointer[-1];
+ null = stack_pointer[-2];
+ callable = stack_pointer[-3];
assert(oparg == 1);
if (null != NULL) goto deoptimize;
- PyObject *obj = args[0];
if (callable != (PyObject *)&PyType_Type) goto deoptimize;
STAT_INC(CALL, hit);
- res = Py_NewRef(Py_TYPE(obj));
- Py_DECREF(obj);
- Py_DECREF(&PyType_Type); // I.e., callable
- stack_pointer[-2 - oparg] = res;
- stack_pointer += -1 - oparg;
+ res = Py_NewRef(Py_TYPE(arg));
+ Py_DECREF(arg);
+ stack_pointer[-3] = res;
+ stack_pointer += -2;
break;
}
case _CALL_STR_1: {
- PyObject **args;
+ PyObject *arg;
PyObject *null;
PyObject *callable;
PyObject *res;
oparg = CURRENT_OPARG();
- args = &stack_pointer[-oparg];
- null = stack_pointer[-1 - oparg];
- callable = stack_pointer[-2 - oparg];
+ arg = stack_pointer[-1];
+ null = stack_pointer[-2];
+ callable = stack_pointer[-3];
assert(oparg == 1);
if (null != NULL) goto deoptimize;
if (callable != (PyObject *)&PyUnicode_Type) goto deoptimize;
STAT_INC(CALL, hit);
- PyObject *arg = args[0];
res = PyObject_Str(arg);
Py_DECREF(arg);
- Py_DECREF(&PyUnicode_Type); // I.e., callable
- if (res == NULL) { stack_pointer += -2 - oparg; goto error_tier_two; }
- stack_pointer[-2 - oparg] = res;
- stack_pointer += -1 - oparg;
+ if (res == NULL) goto pop_3_error_tier_two;
+ stack_pointer[-3] = res;
+ stack_pointer += -2;
CHECK_EVAL_BREAKER();
break;
}
case _CALL_TUPLE_1: {
- PyObject **args;
+ PyObject *arg;
PyObject *null;
PyObject *callable;
PyObject *res;
oparg = CURRENT_OPARG();
- args = &stack_pointer[-oparg];
- null = stack_pointer[-1 - oparg];
- callable = stack_pointer[-2 - oparg];
+ arg = stack_pointer[-1];
+ null = stack_pointer[-2];
+ callable = stack_pointer[-3];
assert(oparg == 1);
if (null != NULL) goto deoptimize;
if (callable != (PyObject *)&PyTuple_Type) goto deoptimize;
STAT_INC(CALL, hit);
- PyObject *arg = args[0];
res = PySequence_Tuple(arg);
Py_DECREF(arg);
- Py_DECREF(&PyTuple_Type); // I.e., tuple
- if (res == NULL) { stack_pointer += -2 - oparg; goto error_tier_two; }
- stack_pointer[-2 - oparg] = res;
- stack_pointer += -1 - oparg;
+ if (res == NULL) goto pop_3_error_tier_two;
+ stack_pointer[-3] = res;
+ stack_pointer += -2;
CHECK_EVAL_BREAKER();
break;
}
next_instr += 4;
INSTRUCTION_STATS(CALL_LIST_APPEND);
static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size");
- PyObject **args;
+ PyObject *arg;
PyObject *self;
PyObject *callable;
/* Skip 1 cache entry */
/* Skip 2 cache entries */
- args = &stack_pointer[-oparg];
- self = stack_pointer[-1 - oparg];
- callable = stack_pointer[-2 - oparg];
+ arg = stack_pointer[-1];
+ self = stack_pointer[-2];
+ callable = stack_pointer[-3];
assert(oparg == 1);
PyInterpreterState *interp = tstate->interp;
DEOPT_IF(callable != interp->callable_cache.list_append, CALL);
assert(self != NULL);
DEOPT_IF(!PyList_Check(self), CALL);
STAT_INC(CALL, hit);
- if (_PyList_AppendTakeRef((PyListObject *)self, args[0]) < 0) {
+ if (_PyList_AppendTakeRef((PyListObject *)self, arg) < 0) {
goto pop_1_error; // Since arg is DECREF'ed already
}
Py_DECREF(self);
next_instr += 4;
INSTRUCTION_STATS(CALL_STR_1);
static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size");
- PyObject **args;
+ PyObject *arg;
PyObject *null;
PyObject *callable;
PyObject *res;
/* Skip 1 cache entry */
/* Skip 2 cache entries */
- args = &stack_pointer[-oparg];
- null = stack_pointer[-1 - oparg];
- callable = stack_pointer[-2 - oparg];
+ arg = stack_pointer[-1];
+ null = stack_pointer[-2];
+ callable = stack_pointer[-3];
assert(oparg == 1);
DEOPT_IF(null != NULL, CALL);
DEOPT_IF(callable != (PyObject *)&PyUnicode_Type, CALL);
STAT_INC(CALL, hit);
- PyObject *arg = args[0];
res = PyObject_Str(arg);
Py_DECREF(arg);
- Py_DECREF(&PyUnicode_Type); // I.e., callable
- if (res == NULL) { stack_pointer += -2 - oparg; goto error; }
- stack_pointer[-2 - oparg] = res;
- stack_pointer += -1 - oparg;
+ if (res == NULL) goto pop_3_error;
+ stack_pointer[-3] = res;
+ stack_pointer += -2;
CHECK_EVAL_BREAKER();
DISPATCH();
}
next_instr += 4;
INSTRUCTION_STATS(CALL_TUPLE_1);
static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size");
- PyObject **args;
+ PyObject *arg;
PyObject *null;
PyObject *callable;
PyObject *res;
/* Skip 1 cache entry */
/* Skip 2 cache entries */
- args = &stack_pointer[-oparg];
- null = stack_pointer[-1 - oparg];
- callable = stack_pointer[-2 - oparg];
+ arg = stack_pointer[-1];
+ null = stack_pointer[-2];
+ callable = stack_pointer[-3];
assert(oparg == 1);
DEOPT_IF(null != NULL, CALL);
DEOPT_IF(callable != (PyObject *)&PyTuple_Type, CALL);
STAT_INC(CALL, hit);
- PyObject *arg = args[0];
res = PySequence_Tuple(arg);
Py_DECREF(arg);
- Py_DECREF(&PyTuple_Type); // I.e., tuple
- if (res == NULL) { stack_pointer += -2 - oparg; goto error; }
- stack_pointer[-2 - oparg] = res;
- stack_pointer += -1 - oparg;
+ if (res == NULL) goto pop_3_error;
+ stack_pointer[-3] = res;
+ stack_pointer += -2;
CHECK_EVAL_BREAKER();
DISPATCH();
}
next_instr += 4;
INSTRUCTION_STATS(CALL_TYPE_1);
static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size");
- PyObject **args;
+ PyObject *arg;
PyObject *null;
PyObject *callable;
PyObject *res;
/* Skip 1 cache entry */
/* Skip 2 cache entries */
- args = &stack_pointer[-oparg];
- null = stack_pointer[-1 - oparg];
- callable = stack_pointer[-2 - oparg];
+ arg = stack_pointer[-1];
+ null = stack_pointer[-2];
+ callable = stack_pointer[-3];
assert(oparg == 1);
DEOPT_IF(null != NULL, CALL);
- PyObject *obj = args[0];
DEOPT_IF(callable != (PyObject *)&PyType_Type, CALL);
STAT_INC(CALL, hit);
- res = Py_NewRef(Py_TYPE(obj));
- Py_DECREF(obj);
- Py_DECREF(&PyType_Type); // I.e., callable
- stack_pointer[-2 - oparg] = res;
- stack_pointer += -1 - oparg;
+ res = Py_NewRef(Py_TYPE(arg));
+ Py_DECREF(arg);
+ stack_pointer[-3] = res;
+ stack_pointer += -2;
DISPATCH();
}
INSTRUCTION_STATS(UNPACK_SEQUENCE_TWO_TUPLE);
static_assert(INLINE_CACHE_ENTRIES_UNPACK_SEQUENCE == 1, "incorrect cache size");
PyObject *seq;
- PyObject **values;
+ PyObject *val1;
+ PyObject *val0;
/* Skip 1 cache entry */
seq = stack_pointer[-1];
- values = &stack_pointer[-1];
+ assert(oparg == 2);
DEOPT_IF(!PyTuple_CheckExact(seq), UNPACK_SEQUENCE);
DEOPT_IF(PyTuple_GET_SIZE(seq) != 2, UNPACK_SEQUENCE);
- assert(oparg == 2);
STAT_INC(UNPACK_SEQUENCE, hit);
- values[0] = Py_NewRef(PyTuple_GET_ITEM(seq, 1));
- values[1] = Py_NewRef(PyTuple_GET_ITEM(seq, 0));
+ val0 = Py_NewRef(PyTuple_GET_ITEM(seq, 0));
+ val1 = Py_NewRef(PyTuple_GET_ITEM(seq, 1));
Py_DECREF(seq);
- stack_pointer += -1 + oparg;
+ stack_pointer[-1] = val1;
+ stack_pointer[0] = val0;
+ stack_pointer += 1;
DISPATCH();
}
}
case _UNPACK_SEQUENCE_TWO_TUPLE: {
- _Py_UopsSymbol **values;
- values = &stack_pointer[-1];
- for (int _i = oparg; --_i >= 0;) {
- values[_i] = sym_new_unknown(ctx);
- if (values[_i] == NULL) goto out_of_space;
- }
- stack_pointer += -1 + oparg;
+ _Py_UopsSymbol *val1;
+ _Py_UopsSymbol *val0;
+ val1 = sym_new_unknown(ctx);
+ if (val1 == NULL) goto out_of_space;
+ val0 = sym_new_unknown(ctx);
+ if (val0 == NULL) goto out_of_space;
+ stack_pointer[-1] = val1;
+ stack_pointer[0] = val0;
+ stack_pointer += 1;
break;
}
_Py_UopsSymbol *res;
res = sym_new_unknown(ctx);
if (res == NULL) goto out_of_space;
- stack_pointer[-2 - oparg] = res;
- stack_pointer += -1 - oparg;
+ stack_pointer[-3] = res;
+ stack_pointer += -2;
break;
}
_Py_UopsSymbol *res;
res = sym_new_unknown(ctx);
if (res == NULL) goto out_of_space;
- stack_pointer[-2 - oparg] = res;
- stack_pointer += -1 - oparg;
+ stack_pointer[-3] = res;
+ stack_pointer += -2;
break;
}
_Py_UopsSymbol *res;
res = sym_new_unknown(ctx);
if (res == NULL) goto out_of_space;
- stack_pointer[-2 - oparg] = res;
- stack_pointer += -1 - oparg;
+ stack_pointer[-3] = res;
+ stack_pointer += -2;
break;
}