@@ -269,7 +269,11 @@ _Py_uop_sym_set_non_null(JitOptContext *ctx, JitOptSymbol *sym)
269269JitOptSymbol *
270270_Py_uop_sym_new_unknown (JitOptContext * ctx )
271271{
272- return sym_new (ctx );
272+ JitOptSymbol * res = sym_new (ctx );
273+ if (res == NULL ) {
274+ return out_of_space (ctx );
275+ }
276+ return res ;
273277}
274278
275279JitOptSymbol *
@@ -444,7 +448,7 @@ _Py_uop_sym_new_tuple(JitOptContext *ctx, int size, JitOptSymbol **args)
444448 if (res == NULL ) {
445449 return out_of_space (ctx );
446450 }
447- if (size > 6 ) {
451+ if (size > MAX_SYMBOLIC_TUPLE_SIZE ) {
448452 res -> tag = JIT_SYM_KNOWN_CLASS_TAG ;
449453 res -> cls .type = & PyTuple_Type ;
450454 }
@@ -461,20 +465,32 @@ _Py_uop_sym_new_tuple(JitOptContext *ctx, int size, JitOptSymbol **args)
461465JitOptSymbol *
462466_Py_uop_sym_tuple_getitem (JitOptContext * ctx , JitOptSymbol * sym , int item )
463467{
464-
465- if (sym -> tag != JIT_SYM_TUPLE_TAG || item < 0 || item >= sym -> tuple .length ) {
466- return _Py_uop_sym_new_unknown (ctx );
468+ assert (item >= 0 );
469+ if (sym -> tag == JIT_SYM_KNOWN_VALUE_TAG ) {
470+ PyObject * tuple = sym -> value .value ;
471+ if (PyTuple_CheckExact (tuple ) && item < PyTuple_GET_SIZE (tuple )) {
472+ return _Py_uop_sym_new_const (ctx , PyTuple_GET_ITEM (tuple , item ));
473+ }
474+ }
475+ else if (sym -> tag == JIT_SYM_TUPLE_TAG && item < sym -> tuple .length ) {
476+ return allocation_base (ctx ) + sym -> tuple .items [item ];
467477 }
468- return allocation_base (ctx ) + sym -> tuple . items [ item ] ;
478+ return _Py_uop_sym_new_unknown (ctx );
469479}
470480
471481int
472482_Py_uop_sym_tuple_length (JitOptSymbol * sym )
473483{
474- if (sym -> tag != JIT_SYM_TUPLE_TAG ) {
475- return -1 ;
484+ if (sym -> tag == JIT_SYM_KNOWN_VALUE_TAG ) {
485+ PyObject * tuple = sym -> value .value ;
486+ if (PyTuple_CheckExact (tuple )) {
487+ return PyTuple_GET_SIZE (tuple );
488+ }
476489 }
477- return sym -> tuple .length ;
490+ else if (sym -> tag == JIT_SYM_TUPLE_TAG ) {
491+ return sym -> tuple .length ;
492+ }
493+ return -1 ;
478494}
479495
480496
@@ -542,6 +558,7 @@ _Py_uop_abstractcontext_fini(JitOptContext *ctx)
542558void
543559_Py_uop_abstractcontext_init (JitOptContext * ctx )
544560{
561+ static_assert (sizeof (JitOptSymbol ) <= 2 * sizeof (uint64_t ));
545562 ctx -> limit = ctx -> locals_and_stack + MAX_ABSTRACT_INTERP_SIZE ;
546563 ctx -> n_consumed = ctx -> locals_and_stack ;
547564#ifdef Py_DEBUG // Aids debugging a little. There should never be NULL in the abstract interpreter.
@@ -694,16 +711,25 @@ _Py_uop_symbols_test(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(ignored))
694711 _Py_uop_sym_get_const (_Py_uop_sym_tuple_getitem (ctx , sym , 1 )) == val_43 ,
695712 "tuple item does not match value used to create tuple"
696713 );
714+ PyObject * pair [2 ] = { val_42 , val_43 };
715+ PyObject * tuple = _PyTuple_FromArray (pair , 2 );
716+ sym = _Py_uop_sym_new_const (ctx , tuple );
717+ TEST_PREDICATE (
718+ _Py_uop_sym_get_const (_Py_uop_sym_tuple_getitem (ctx , sym , 1 )) == val_43 ,
719+ "tuple item does not match value used to create tuple"
720+ );
697721
698722 _Py_uop_abstractcontext_fini (ctx );
699723 Py_DECREF (val_42 );
700724 Py_DECREF (val_43 );
725+ Py_DECREF (tuple );
701726 Py_RETURN_NONE ;
702727
703728fail :
704729 _Py_uop_abstractcontext_fini (ctx );
705730 Py_XDECREF (val_42 );
706731 Py_XDECREF (val_43 );
732+ Py_DECREF (tuple );
707733 return NULL ;
708734}
709735
0 commit comments