This commit is contained in:
Hai Zhu 2025-12-23 14:14:09 +05:30 committed by GitHub
commit 2315ebb326
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 263 additions and 98 deletions

View file

@ -1507,10 +1507,10 @@ _PyOpcode_macro_expansion[256] = {
[UNARY_NEGATIVE] = { .nuops = 1, .uops = { { _UNARY_NEGATIVE, OPARG_SIMPLE, 0 } } },
[UNARY_NOT] = { .nuops = 1, .uops = { { _UNARY_NOT, OPARG_SIMPLE, 0 } } },
[UNPACK_EX] = { .nuops = 1, .uops = { { _UNPACK_EX, OPARG_SIMPLE, 0 } } },
[UNPACK_SEQUENCE] = { .nuops = 1, .uops = { { _UNPACK_SEQUENCE, OPARG_SIMPLE, 0 } } },
[UNPACK_SEQUENCE_LIST] = { .nuops = 2, .uops = { { _GUARD_TOS_LIST, OPARG_SIMPLE, 0 }, { _UNPACK_SEQUENCE_LIST, OPARG_SIMPLE, 1 } } },
[UNPACK_SEQUENCE_TUPLE] = { .nuops = 2, .uops = { { _GUARD_TOS_TUPLE, OPARG_SIMPLE, 0 }, { _UNPACK_SEQUENCE_TUPLE, OPARG_SIMPLE, 1 } } },
[UNPACK_SEQUENCE_TWO_TUPLE] = { .nuops = 2, .uops = { { _GUARD_TOS_TUPLE, OPARG_SIMPLE, 0 }, { _UNPACK_SEQUENCE_TWO_TUPLE, OPARG_SIMPLE, 1 } } },
[UNPACK_SEQUENCE] = { .nuops = 2, .uops = { { _UNPACK_SEQUENCE, OPARG_SIMPLE, 0 }, { _POP_TOP, OPARG_SIMPLE, 0 } } },
[UNPACK_SEQUENCE_LIST] = { .nuops = 3, .uops = { { _GUARD_TOS_LIST, OPARG_SIMPLE, 0 }, { _UNPACK_SEQUENCE_LIST, OPARG_SIMPLE, 1 }, { _POP_TOP, OPARG_SIMPLE, 1 } } },
[UNPACK_SEQUENCE_TUPLE] = { .nuops = 3, .uops = { { _GUARD_TOS_TUPLE, OPARG_SIMPLE, 0 }, { _UNPACK_SEQUENCE_TUPLE, OPARG_SIMPLE, 1 }, { _POP_TOP, OPARG_SIMPLE, 1 } } },
[UNPACK_SEQUENCE_TWO_TUPLE] = { .nuops = 3, .uops = { { _GUARD_TOS_TUPLE, OPARG_SIMPLE, 0 }, { _UNPACK_SEQUENCE_TWO_TUPLE, OPARG_SIMPLE, 1 }, { _POP_TOP, OPARG_SIMPLE, 1 } } },
[WITH_EXCEPT_START] = { .nuops = 1, .uops = { { _WITH_EXCEPT_START, OPARG_SIMPLE, 0 } } },
[YIELD_VALUE] = { .nuops = 1, .uops = { { _YIELD_VALUE, OPARG_SIMPLE, 0 } } },
};

View file

@ -1096,13 +1096,14 @@ extern "C" {
#define _UNARY_NOT_r22 1289
#define _UNARY_NOT_r33 1290
#define _UNPACK_EX_r10 1291
#define _UNPACK_SEQUENCE_r10 1292
#define _UNPACK_SEQUENCE_LIST_r10 1293
#define _UNPACK_SEQUENCE_TUPLE_r10 1294
#define _UNPACK_SEQUENCE_TWO_TUPLE_r12 1295
#define _WITH_EXCEPT_START_r33 1296
#define _YIELD_VALUE_r11 1297
#define MAX_UOP_REGS_ID 1297
#define _UNPACK_SEQUENCE_r11 1292
#define _UNPACK_SEQUENCE_LIST_r11 1293
#define _UNPACK_SEQUENCE_TUPLE_r11 1294
#define _UNPACK_SEQUENCE_TWO_TUPLE_r03 1295
#define _UNPACK_SEQUENCE_TWO_TUPLE_r13 1296
#define _WITH_EXCEPT_START_r33 1297
#define _YIELD_VALUE_r11 1298
#define MAX_UOP_REGS_ID 1298
#ifdef __cplusplus
}

View file

@ -148,9 +148,9 @@ const uint32_t _PyUop_Flags[MAX_UOP_ID+1] = {
[_STORE_NAME] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
[_DELETE_NAME] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG,
[_UNPACK_SEQUENCE] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
[_UNPACK_SEQUENCE_TWO_TUPLE] = HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG,
[_UNPACK_SEQUENCE_TUPLE] = HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG,
[_UNPACK_SEQUENCE_LIST] = HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG,
[_UNPACK_SEQUENCE_TWO_TUPLE] = HAS_ARG_FLAG | HAS_DEOPT_FLAG,
[_UNPACK_SEQUENCE_TUPLE] = HAS_ARG_FLAG | HAS_DEOPT_FLAG,
[_UNPACK_SEQUENCE_LIST] = HAS_ARG_FLAG | HAS_DEOPT_FLAG,
[_UNPACK_EX] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
[_STORE_ATTR] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
[_DELETE_ATTR] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
@ -1378,16 +1378,16 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
.best = { 1, 1, 1, 1 },
.entries = {
{ -1, -1, -1 },
{ 0, 1, _UNPACK_SEQUENCE_r10 },
{ 1, 1, _UNPACK_SEQUENCE_r11 },
{ -1, -1, -1 },
{ -1, -1, -1 },
},
},
[_UNPACK_SEQUENCE_TWO_TUPLE] = {
.best = { 1, 1, 1, 1 },
.best = { 0, 1, 1, 1 },
.entries = {
{ -1, -1, -1 },
{ 2, 1, _UNPACK_SEQUENCE_TWO_TUPLE_r12 },
{ 3, 0, _UNPACK_SEQUENCE_TWO_TUPLE_r03 },
{ 3, 1, _UNPACK_SEQUENCE_TWO_TUPLE_r13 },
{ -1, -1, -1 },
{ -1, -1, -1 },
},
@ -1396,7 +1396,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
.best = { 1, 1, 1, 1 },
.entries = {
{ -1, -1, -1 },
{ 0, 1, _UNPACK_SEQUENCE_TUPLE_r10 },
{ 1, 1, _UNPACK_SEQUENCE_TUPLE_r11 },
{ -1, -1, -1 },
{ -1, -1, -1 },
},
@ -1405,7 +1405,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
.best = { 1, 1, 1, 1 },
.entries = {
{ -1, -1, -1 },
{ 0, 1, _UNPACK_SEQUENCE_LIST_r10 },
{ 1, 1, _UNPACK_SEQUENCE_LIST_r11 },
{ -1, -1, -1 },
{ -1, -1, -1 },
},
@ -3479,10 +3479,11 @@ const uint16_t _PyUop_Uncached[MAX_UOP_REGS_ID+1] = {
[_LOAD_BUILD_CLASS_r01] = _LOAD_BUILD_CLASS,
[_STORE_NAME_r10] = _STORE_NAME,
[_DELETE_NAME_r00] = _DELETE_NAME,
[_UNPACK_SEQUENCE_r10] = _UNPACK_SEQUENCE,
[_UNPACK_SEQUENCE_TWO_TUPLE_r12] = _UNPACK_SEQUENCE_TWO_TUPLE,
[_UNPACK_SEQUENCE_TUPLE_r10] = _UNPACK_SEQUENCE_TUPLE,
[_UNPACK_SEQUENCE_LIST_r10] = _UNPACK_SEQUENCE_LIST,
[_UNPACK_SEQUENCE_r11] = _UNPACK_SEQUENCE,
[_UNPACK_SEQUENCE_TWO_TUPLE_r03] = _UNPACK_SEQUENCE_TWO_TUPLE,
[_UNPACK_SEQUENCE_TWO_TUPLE_r13] = _UNPACK_SEQUENCE_TWO_TUPLE,
[_UNPACK_SEQUENCE_TUPLE_r11] = _UNPACK_SEQUENCE_TUPLE,
[_UNPACK_SEQUENCE_LIST_r11] = _UNPACK_SEQUENCE_LIST,
[_UNPACK_EX_r10] = _UNPACK_EX,
[_STORE_ATTR_r20] = _STORE_ATTR,
[_DELETE_ATTR_r10] = _DELETE_ATTR,
@ -4887,13 +4888,14 @@ const char *const _PyOpcode_uop_name[MAX_UOP_REGS_ID+1] = {
[_UNPACK_EX] = "_UNPACK_EX",
[_UNPACK_EX_r10] = "_UNPACK_EX_r10",
[_UNPACK_SEQUENCE] = "_UNPACK_SEQUENCE",
[_UNPACK_SEQUENCE_r10] = "_UNPACK_SEQUENCE_r10",
[_UNPACK_SEQUENCE_r11] = "_UNPACK_SEQUENCE_r11",
[_UNPACK_SEQUENCE_LIST] = "_UNPACK_SEQUENCE_LIST",
[_UNPACK_SEQUENCE_LIST_r10] = "_UNPACK_SEQUENCE_LIST_r10",
[_UNPACK_SEQUENCE_LIST_r11] = "_UNPACK_SEQUENCE_LIST_r11",
[_UNPACK_SEQUENCE_TUPLE] = "_UNPACK_SEQUENCE_TUPLE",
[_UNPACK_SEQUENCE_TUPLE_r10] = "_UNPACK_SEQUENCE_TUPLE_r10",
[_UNPACK_SEQUENCE_TUPLE_r11] = "_UNPACK_SEQUENCE_TUPLE_r11",
[_UNPACK_SEQUENCE_TWO_TUPLE] = "_UNPACK_SEQUENCE_TWO_TUPLE",
[_UNPACK_SEQUENCE_TWO_TUPLE_r12] = "_UNPACK_SEQUENCE_TWO_TUPLE_r12",
[_UNPACK_SEQUENCE_TWO_TUPLE_r03] = "_UNPACK_SEQUENCE_TWO_TUPLE_r03",
[_UNPACK_SEQUENCE_TWO_TUPLE_r13] = "_UNPACK_SEQUENCE_TWO_TUPLE_r13",
[_WITH_EXCEPT_START] = "_WITH_EXCEPT_START",
[_WITH_EXCEPT_START_r33] = "_WITH_EXCEPT_START_r33",
[_YIELD_VALUE] = "_YIELD_VALUE",

View file

@ -433,6 +433,75 @@ class TestUops(unittest.TestCase):
uops = get_opnames(ex)
self.assertIn("_FOR_ITER_TIER_TWO", uops)
def test_unpack_sequence_generic(self):
def testfunc(x):
i = 0
while i < x:
i += 1
# Use an iterator to force generic UNPACK_SEQUENCE
a, b = iter((1, 2))
return a, b
res = testfunc(TIER2_THRESHOLD)
self.assertEqual(res, (1, 2))
ex = get_first_executor(testfunc)
self.assertIsNotNone(ex)
uops = get_opnames(ex)
self.assertIn("_UNPACK_SEQUENCE", uops)
def test_unpack_sequence_two_tuple(self):
def testfunc(x):
i = 0
while i < x:
i += 1
t = (i, i)
a, b = t
return a, b
res = testfunc(TIER2_THRESHOLD)
self.assertEqual(res, (TIER2_THRESHOLD, TIER2_THRESHOLD))
ex = get_first_executor(testfunc)
self.assertIsNotNone(ex)
uops = get_opnames(ex)
self.assertIn("_UNPACK_SEQUENCE_TWO_TUPLE", uops)
self.assertNotIn("_POP_TOP", uops)
def test_unpack_sequence_tuple(self):
def testfunc(x):
i = 0
while i < x:
i += 1
t = (i, i, i)
a, b, c = t
return a, b, c
res = testfunc(TIER2_THRESHOLD)
self.assertEqual(res, (TIER2_THRESHOLD, TIER2_THRESHOLD, TIER2_THRESHOLD))
ex = get_first_executor(testfunc)
self.assertIsNotNone(ex)
uops = get_opnames(ex)
self.assertIn("_UNPACK_SEQUENCE_TUPLE", uops)
self.assertNotIn("_POP_TOP", uops)
def test_unpack_sequence_list(self):
def testfunc(x):
i = 0
while i < x:
i += 1
a, b = [1, 2]
return a, b
res = testfunc(TIER2_THRESHOLD)
self.assertEqual(res, (1, 2))
ex = get_first_executor(testfunc)
self.assertIsNotNone(ex)
uops = get_opnames(ex)
self.assertIn("_UNPACK_SEQUENCE_LIST", uops)
@requires_specialization
@unittest.skipIf(Py_GIL_DISABLED, "optimizer not yet supported in free-threaded builds")

View file

@ -1577,19 +1577,23 @@ dummy_func(
(void)counter;
}
op(_UNPACK_SEQUENCE, (seq -- unused[oparg], top[0])) {
PyObject *seq_o = PyStackRef_AsPyObjectSteal(seq);
op(_UNPACK_SEQUENCE, (seq -- unused[oparg], top[0], s)) {
PyObject *seq_o = PyStackRef_AsPyObjectBorrow(seq);
int res = _PyEval_UnpackIterableStackRef(tstate, seq_o, oparg, -1, top);
Py_DECREF(seq_o);
ERROR_IF(res == 0);
if (res == 0) {
PyStackRef_CLOSE(seq);
ERROR_IF(1);
}
s = seq;
INPUTS_DEAD();
}
macro(UNPACK_SEQUENCE) = _SPECIALIZE_UNPACK_SEQUENCE + _UNPACK_SEQUENCE;
macro(UNPACK_SEQUENCE) = _SPECIALIZE_UNPACK_SEQUENCE + _UNPACK_SEQUENCE + POP_TOP;
macro(UNPACK_SEQUENCE_TWO_TUPLE) =
_GUARD_TOS_TUPLE + unused/1 + _UNPACK_SEQUENCE_TWO_TUPLE;
_GUARD_TOS_TUPLE + unused/1 + _UNPACK_SEQUENCE_TWO_TUPLE + POP_TOP;
op(_UNPACK_SEQUENCE_TWO_TUPLE, (seq -- val1, val0)) {
op(_UNPACK_SEQUENCE_TWO_TUPLE, (seq -- val1, val0, s)) {
assert(oparg == 2);
PyObject *seq_o = PyStackRef_AsPyObjectBorrow(seq);
assert(PyTuple_CheckExact(seq_o));
@ -1597,13 +1601,14 @@ dummy_func(
STAT_INC(UNPACK_SEQUENCE, hit);
val0 = PyStackRef_FromPyObjectNew(PyTuple_GET_ITEM(seq_o, 0));
val1 = PyStackRef_FromPyObjectNew(PyTuple_GET_ITEM(seq_o, 1));
PyStackRef_CLOSE(seq);
s = seq;
INPUTS_DEAD();
}
macro(UNPACK_SEQUENCE_TUPLE) =
_GUARD_TOS_TUPLE + unused/1 + _UNPACK_SEQUENCE_TUPLE;
_GUARD_TOS_TUPLE + unused/1 + _UNPACK_SEQUENCE_TUPLE + POP_TOP;
op(_UNPACK_SEQUENCE_TUPLE, (seq -- values[oparg])) {
op(_UNPACK_SEQUENCE_TUPLE, (seq -- values[oparg], s)) {
PyObject *seq_o = PyStackRef_AsPyObjectBorrow(seq);
assert(PyTuple_CheckExact(seq_o));
DEOPT_IF(PyTuple_GET_SIZE(seq_o) != oparg);
@ -1612,13 +1617,14 @@ dummy_func(
for (int i = oparg; --i >= 0; ) {
*values++ = PyStackRef_FromPyObjectNew(items[i]);
}
DECREF_INPUTS();
s = seq;
INPUTS_DEAD();
}
macro(UNPACK_SEQUENCE_LIST) =
_GUARD_TOS_LIST + unused/1 + _UNPACK_SEQUENCE_LIST;
_GUARD_TOS_LIST + unused/1 + _UNPACK_SEQUENCE_LIST + POP_TOP;
op(_UNPACK_SEQUENCE_LIST, (seq -- values[oparg])) {
op(_UNPACK_SEQUENCE_LIST, (seq -- values[oparg], s)) {
PyObject *seq_o = PyStackRef_AsPyObjectBorrow(seq);
assert(PyList_CheckExact(seq_o));
DEOPT_IF(!LOCK_OBJECT(seq_o));
@ -1632,7 +1638,8 @@ dummy_func(
*values++ = PyStackRef_FromPyObjectNew(items[i]);
}
UNLOCK_OBJECT(seq_o);
DECREF_INPUTS();
s = seq;
INPUTS_DEAD();
}
inst(UNPACK_EX, (seq -- unused[oparg & 0xFF], unused, unused[oparg >> 8], top[0])) {

View file

@ -6084,40 +6084,81 @@
break;
}
case _UNPACK_SEQUENCE_r10: {
case _UNPACK_SEQUENCE_r11: {
CHECK_CURRENT_CACHED_VALUES(1);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
_PyStackRef seq;
_PyStackRef *top;
_PyStackRef s;
_PyStackRef _stack_item_0 = _tos_cache0;
oparg = CURRENT_OPARG();
seq = _stack_item_0;
top = &stack_pointer[oparg];
PyObject *seq_o = PyStackRef_AsPyObjectSteal(seq);
PyObject *seq_o = PyStackRef_AsPyObjectBorrow(seq);
stack_pointer[0] = seq;
stack_pointer += 1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
_PyFrame_SetStackPointer(frame, stack_pointer);
int res = _PyEval_UnpackIterableStackRef(tstate, seq_o, oparg, -1, top);
Py_DECREF(seq_o);
stack_pointer = _PyFrame_GetStackPointer(frame);
if (res == 0) {
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
_PyFrame_SetStackPointer(frame, stack_pointer);
PyStackRef_CLOSE(seq);
stack_pointer = _PyFrame_GetStackPointer(frame);
SET_CURRENT_CACHED_VALUES(0);
JUMP_TO_ERROR();
}
_tos_cache0 = PyStackRef_ZERO_BITS;
s = seq;
_tos_cache0 = s;
_tos_cache1 = PyStackRef_ZERO_BITS;
_tos_cache2 = PyStackRef_ZERO_BITS;
SET_CURRENT_CACHED_VALUES(0);
stack_pointer += oparg;
SET_CURRENT_CACHED_VALUES(1);
stack_pointer += -1 + oparg;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
break;
}
case _UNPACK_SEQUENCE_TWO_TUPLE_r12: {
case _UNPACK_SEQUENCE_TWO_TUPLE_r03: {
CHECK_CURRENT_CACHED_VALUES(0);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
_PyStackRef seq;
_PyStackRef val1;
_PyStackRef val0;
_PyStackRef s;
oparg = CURRENT_OPARG();
seq = stack_pointer[-1];
assert(oparg == 2);
PyObject *seq_o = PyStackRef_AsPyObjectBorrow(seq);
assert(PyTuple_CheckExact(seq_o));
if (PyTuple_GET_SIZE(seq_o) != 2) {
UOP_STAT_INC(uopcode, miss);
SET_CURRENT_CACHED_VALUES(0);
JUMP_TO_JUMP_TARGET();
}
STAT_INC(UNPACK_SEQUENCE, hit);
val0 = PyStackRef_FromPyObjectNew(PyTuple_GET_ITEM(seq_o, 0));
val1 = PyStackRef_FromPyObjectNew(PyTuple_GET_ITEM(seq_o, 1));
s = seq;
_tos_cache2 = s;
_tos_cache1 = val0;
_tos_cache0 = val1;
SET_CURRENT_CACHED_VALUES(3);
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
break;
}
case _UNPACK_SEQUENCE_TWO_TUPLE_r13: {
CHECK_CURRENT_CACHED_VALUES(1);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
_PyStackRef seq;
_PyStackRef val1;
_PyStackRef val0;
_PyStackRef s;
_PyStackRef _stack_item_0 = _tos_cache0;
oparg = CURRENT_OPARG();
seq = _stack_item_0;
@ -6133,28 +6174,21 @@
STAT_INC(UNPACK_SEQUENCE, hit);
val0 = PyStackRef_FromPyObjectNew(PyTuple_GET_ITEM(seq_o, 0));
val1 = PyStackRef_FromPyObjectNew(PyTuple_GET_ITEM(seq_o, 1));
stack_pointer[0] = val1;
stack_pointer[1] = val0;
stack_pointer += 2;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
_PyFrame_SetStackPointer(frame, stack_pointer);
PyStackRef_CLOSE(seq);
stack_pointer = _PyFrame_GetStackPointer(frame);
s = seq;
_tos_cache2 = s;
_tos_cache1 = val0;
_tos_cache0 = val1;
_tos_cache2 = PyStackRef_ZERO_BITS;
SET_CURRENT_CACHED_VALUES(2);
stack_pointer += -2;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
SET_CURRENT_CACHED_VALUES(3);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
break;
}
case _UNPACK_SEQUENCE_TUPLE_r10: {
case _UNPACK_SEQUENCE_TUPLE_r11: {
CHECK_CURRENT_CACHED_VALUES(1);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
_PyStackRef seq;
_PyStackRef *values;
_PyStackRef s;
_PyStackRef _stack_item_0 = _tos_cache0;
oparg = CURRENT_OPARG();
seq = _stack_item_0;
@ -6172,24 +6206,21 @@
for (int i = oparg; --i >= 0; ) {
*values++ = PyStackRef_FromPyObjectNew(items[i]);
}
s = seq;
_tos_cache0 = s;
SET_CURRENT_CACHED_VALUES(1);
stack_pointer += oparg;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
_PyFrame_SetStackPointer(frame, stack_pointer);
PyStackRef_CLOSE(seq);
stack_pointer = _PyFrame_GetStackPointer(frame);
_tos_cache0 = PyStackRef_ZERO_BITS;
_tos_cache1 = PyStackRef_ZERO_BITS;
_tos_cache2 = PyStackRef_ZERO_BITS;
SET_CURRENT_CACHED_VALUES(0);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
break;
}
case _UNPACK_SEQUENCE_LIST_r10: {
case _UNPACK_SEQUENCE_LIST_r11: {
CHECK_CURRENT_CACHED_VALUES(1);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
_PyStackRef seq;
_PyStackRef *values;
_PyStackRef s;
_PyStackRef _stack_item_0 = _tos_cache0;
oparg = CURRENT_OPARG();
seq = _stack_item_0;
@ -6217,15 +6248,11 @@
*values++ = PyStackRef_FromPyObjectNew(items[i]);
}
UNLOCK_OBJECT(seq_o);
s = seq;
_tos_cache0 = s;
SET_CURRENT_CACHED_VALUES(1);
stack_pointer += oparg;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
_PyFrame_SetStackPointer(frame, stack_pointer);
PyStackRef_CLOSE(seq);
stack_pointer = _PyFrame_GetStackPointer(frame);
_tos_cache0 = PyStackRef_ZERO_BITS;
_tos_cache1 = PyStackRef_ZERO_BITS;
_tos_cache2 = PyStackRef_ZERO_BITS;
SET_CURRENT_CACHED_VALUES(0);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
break;
}

View file

@ -11548,6 +11548,8 @@
(void)this_instr;
_PyStackRef seq;
_PyStackRef *top;
_PyStackRef s;
_PyStackRef value;
// _SPECIALIZE_UNPACK_SEQUENCE
{
seq = stack_pointer[-1];
@ -11570,19 +11572,29 @@
// _UNPACK_SEQUENCE
{
top = &stack_pointer[-1 + oparg];
PyObject *seq_o = PyStackRef_AsPyObjectSteal(seq);
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
PyObject *seq_o = PyStackRef_AsPyObjectBorrow(seq);
_PyFrame_SetStackPointer(frame, stack_pointer);
int res = _PyEval_UnpackIterableStackRef(tstate, seq_o, oparg, -1, top);
Py_DECREF(seq_o);
stack_pointer = _PyFrame_GetStackPointer(frame);
if (res == 0) {
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
_PyFrame_SetStackPointer(frame, stack_pointer);
PyStackRef_CLOSE(seq);
stack_pointer = _PyFrame_GetStackPointer(frame);
JUMP_TO_LABEL(error);
}
s = seq;
}
// _POP_TOP
{
value = s;
stack_pointer += -1 + oparg;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
_PyFrame_SetStackPointer(frame, stack_pointer);
PyStackRef_XCLOSE(value);
stack_pointer = _PyFrame_GetStackPointer(frame);
}
stack_pointer += oparg;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
DISPATCH();
}
@ -11600,6 +11612,8 @@
_PyStackRef tos;
_PyStackRef seq;
_PyStackRef *values;
_PyStackRef s;
_PyStackRef value;
// _GUARD_TOS_LIST
{
tos = stack_pointer[-1];
@ -11636,10 +11650,15 @@
*values++ = PyStackRef_FromPyObjectNew(items[i]);
}
UNLOCK_OBJECT(seq_o);
s = seq;
}
// _POP_TOP
{
value = s;
stack_pointer += -1 + oparg;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
_PyFrame_SetStackPointer(frame, stack_pointer);
PyStackRef_CLOSE(seq);
PyStackRef_XCLOSE(value);
stack_pointer = _PyFrame_GetStackPointer(frame);
}
DISPATCH();
@ -11659,6 +11678,8 @@
_PyStackRef tos;
_PyStackRef seq;
_PyStackRef *values;
_PyStackRef s;
_PyStackRef value;
// _GUARD_TOS_TUPLE
{
tos = stack_pointer[-1];
@ -11686,10 +11707,15 @@
for (int i = oparg; --i >= 0; ) {
*values++ = PyStackRef_FromPyObjectNew(items[i]);
}
s = seq;
}
// _POP_TOP
{
value = s;
stack_pointer += -1 + oparg;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
_PyFrame_SetStackPointer(frame, stack_pointer);
PyStackRef_CLOSE(seq);
PyStackRef_XCLOSE(value);
stack_pointer = _PyFrame_GetStackPointer(frame);
}
DISPATCH();
@ -11710,6 +11736,8 @@
_PyStackRef seq;
_PyStackRef val1;
_PyStackRef val0;
_PyStackRef s;
_PyStackRef value;
// _GUARD_TOS_TUPLE
{
tos = stack_pointer[-1];
@ -11735,12 +11763,17 @@
STAT_INC(UNPACK_SEQUENCE, hit);
val0 = PyStackRef_FromPyObjectNew(PyTuple_GET_ITEM(seq_o, 0));
val1 = PyStackRef_FromPyObjectNew(PyTuple_GET_ITEM(seq_o, 1));
s = seq;
}
// _POP_TOP
{
value = s;
stack_pointer[-1] = val1;
stack_pointer[0] = val0;
stack_pointer += 1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
_PyFrame_SetStackPointer(frame, stack_pointer);
PyStackRef_CLOSE(seq);
PyStackRef_XCLOSE(value);
stack_pointer = _PyFrame_GetStackPointer(frame);
}
DISPATCH();

View file

@ -953,12 +953,13 @@ dummy_func(void) {
}
}
op(_UNPACK_SEQUENCE, (seq -- values[oparg], top[0])) {
op(_UNPACK_SEQUENCE, (seq -- values[oparg], top[0], s)) {
(void)top;
/* This has to be done manually */
for (int i = 0; i < oparg; i++) {
values[i] = sym_new_unknown(ctx);
}
s = seq;
}
op(_UNPACK_EX, (seq -- values[oparg & 0xFF], unused, unused[oparg >> 8], top[0])) {
@ -1135,15 +1136,24 @@ dummy_func(void) {
set = sym_new_type(ctx, &PySet_Type);
}
op(_UNPACK_SEQUENCE_TWO_TUPLE, (seq -- val1, val0)) {
op(_UNPACK_SEQUENCE_TWO_TUPLE, (seq -- val1, val0, s)) {
val0 = sym_tuple_getitem(ctx, seq, 0);
val1 = sym_tuple_getitem(ctx, seq, 1);
s = seq;
}
op(_UNPACK_SEQUENCE_TUPLE, (seq -- values[oparg])) {
op(_UNPACK_SEQUENCE_TUPLE, (seq -- values[oparg], s)) {
for (int i = 0; i < oparg; i++) {
values[i] = sym_tuple_getitem(ctx, seq, oparg - i - 1);
}
s = seq;
}
op(_UNPACK_SEQUENCE_LIST, (seq -- values[oparg], s)) {
for (int i = 0; i < oparg; i++) {
values[i] = sym_new_not_null(ctx);
}
s = seq;
}
op(_CALL_TUPLE_1, (callable, null, arg -- res, a)) {

View file

@ -1128,16 +1128,21 @@
}
case _UNPACK_SEQUENCE: {
JitOptRef seq;
JitOptRef *values;
JitOptRef *top;
JitOptRef s;
seq = stack_pointer[-1];
values = &stack_pointer[-1];
top = &stack_pointer[-1 + oparg];
(void)top;
for (int i = 0; i < oparg; i++) {
values[i] = sym_new_unknown(ctx);
}
CHECK_STACK_BOUNDS(-1 + oparg);
stack_pointer += -1 + oparg;
s = seq;
CHECK_STACK_BOUNDS(oparg);
stack_pointer[-1 + oparg] = s;
stack_pointer += oparg;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
}
@ -1146,13 +1151,16 @@
JitOptRef seq;
JitOptRef val1;
JitOptRef val0;
JitOptRef s;
seq = stack_pointer[-1];
val0 = sym_tuple_getitem(ctx, seq, 0);
val1 = sym_tuple_getitem(ctx, seq, 1);
CHECK_STACK_BOUNDS(1);
s = seq;
CHECK_STACK_BOUNDS(2);
stack_pointer[-1] = val1;
stack_pointer[0] = val0;
stack_pointer += 1;
stack_pointer[1] = s;
stack_pointer += 2;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
}
@ -1160,25 +1168,33 @@
case _UNPACK_SEQUENCE_TUPLE: {
JitOptRef seq;
JitOptRef *values;
JitOptRef s;
seq = stack_pointer[-1];
values = &stack_pointer[-1];
for (int i = 0; i < oparg; i++) {
values[i] = sym_tuple_getitem(ctx, seq, oparg - i - 1);
}
CHECK_STACK_BOUNDS(-1 + oparg);
stack_pointer += -1 + oparg;
s = seq;
CHECK_STACK_BOUNDS(oparg);
stack_pointer[-1 + oparg] = s;
stack_pointer += oparg;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
}
case _UNPACK_SEQUENCE_LIST: {
JitOptRef seq;
JitOptRef *values;
JitOptRef s;
seq = stack_pointer[-1];
values = &stack_pointer[-1];
for (int _i = oparg; --_i >= 0;) {
values[_i] = sym_new_not_null(ctx);
for (int i = 0; i < oparg; i++) {
values[i] = sym_new_not_null(ctx);
}
CHECK_STACK_BOUNDS(-1 + oparg);
stack_pointer += -1 + oparg;
s = seq;
CHECK_STACK_BOUNDS(oparg);
stack_pointer[-1 + oparg] = s;
stack_pointer += oparg;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
}