comparison Python/compile.c @ 34574:369e8e71ea33 legacy-trunk

Remove the set conversion which didn't work with: [] in (0,)
author Raymond Hettinger <python@rcn.com>
date Thu, 10 Feb 2005 01:42:32 +0000
parents e67b587fed77
children 516bb8fd75b4
comparison
equal deleted inserted replaced
34572:3c172c826eed 34574:369e8e71ea33
540 codestr[4] = LOAD_CONST; 540 codestr[4] = LOAD_CONST;
541 SETARG(codestr, 4, len_consts); 541 SETARG(codestr, 4, len_consts);
542 return 1; 542 return 1;
543 } 543 }
544 544
545 /* Replace LOAD_CONST tuple with LOAD_CONST frozenset in the context
546 of a single-use constant for "in" and "not in" tests.
547 */
548 int
549 try_set_conversion(unsigned char *codestr, PyObject *consts)
550 {
551 PyObject *newconst, *constant;
552 int arg, len_consts;
553
554 /* Pre-conditions */
555 assert(PyList_CheckExact(consts));
556 assert(codestr[0] == LOAD_CONST);
557 assert(codestr[3] == COMPARE_OP);
558 assert(GETARG(codestr, 3) == 6 || GETARG(codestr, 3) == 7);
559
560 /* Attempt to convert constant to a frozenset. Bail-out with no
561 changes if the tuple contains unhashable values. */
562 arg = GETARG(codestr, 0);
563 constant = PyList_GET_ITEM(consts, arg);
564 if (constant->ob_type != &PyTuple_Type)
565 return 0;
566 newconst = PyObject_CallFunctionObjArgs(
567 (PyObject *)&PyFrozenSet_Type, constant, NULL);
568 if (newconst == NULL) {
569 PyErr_Clear();
570 return 0;
571 }
572
573 /* Append new constant onto consts list or replace existing constant
574 if there are no other references to it.*/
575 if (constant->ob_refcnt == 1) {
576 PyList_SET_ITEM(consts, arg, newconst);
577 Py_DECREF(constant);
578 return 1;
579 }
580 len_consts = PyList_GET_SIZE(consts);
581 if (PyList_Append(consts, newconst)) {
582 Py_DECREF(newconst);
583 return 0;
584 }
585 Py_DECREF(newconst);
586
587 /* Write new LOAD_CONST newconst on top of LOAD_CONST oldconst */
588 SETARG(codestr, 0, len_consts);
589 return 1;
590 }
591
592 static unsigned int * 545 static unsigned int *
593 markblocks(unsigned char *code, int len) 546 markblocks(unsigned char *code, int len)
594 { 547 {
595 unsigned int *blocks = PyMem_Malloc(len*sizeof(int)); 548 unsigned int *blocks = PyMem_Malloc(len*sizeof(int));
596 int i,j, opcode, blockcnt = 0; 549 int i,j, opcode, blockcnt = 0;
712 break; 665 break;
713 666
714 /* not a is b --> a is not b 667 /* not a is b --> a is not b
715 not a in b --> a not in b 668 not a in b --> a not in b
716 not a is not b --> a is b 669 not a is not b --> a is b
717 not a not in b --> a in b 670 not a not in b --> a in b
718
719 a in c --> a in frozenset(c)
720 where c is a constant tuple of hashable values
721 */ 671 */
722 case COMPARE_OP: 672 case COMPARE_OP:
723 j = GETARG(codestr, i); 673 j = GETARG(codestr, i);
724 if (lastlc >= 1 && (j == 6 || j == 7) && ISBASICBLOCK(blocks,i-3,6))
725 try_set_conversion(&codestr[i-3], consts);
726 if (j < 6 || j > 9 || 674 if (j < 6 || j > 9 ||
727 codestr[i+3] != UNARY_NOT || 675 codestr[i+3] != UNARY_NOT ||
728 !ISBASICBLOCK(blocks,i,4)) 676 !ISBASICBLOCK(blocks,i,4))
729 continue; 677 continue;
730 SETARG(codestr, i, (j^1)); 678 SETARG(codestr, i, (j^1));