@@ -595,17 +595,52 @@ static int
595595instr_sequence_to_cfg (instr_sequence * seq , cfg_builder * g ) {
596596 memset (g , 0 , sizeof (cfg_builder ));
597597 RETURN_IF_ERROR (cfg_builder_init (g ));
598- /* Note: there can be more than one label for the same offset */
598+
599+ /* There can be more than one label for the same offset. The
600+ * offset2lbl maping selects one of them which we use consistently.
601+ */
602+
603+ int * offset2lbl = PyMem_Malloc (seq -> s_used * sizeof (int ));
604+ if (offset2lbl == NULL ) {
605+ PyErr_NoMemory ();
606+ return ERROR ;
607+ }
599608 for (int i = 0 ; i < seq -> s_used ; i ++ ) {
600- for (int j = 0 ; j < seq -> s_labelmap_size ; j ++ ) {
601- if (seq -> s_labelmap [j ] == i ) {
602- jump_target_label lbl = {j };
603- RETURN_IF_ERROR (cfg_builder_use_label (g , lbl ));
609+ offset2lbl [i ] = -1 ;
610+ }
611+ for (int lbl = 0 ; lbl < seq -> s_labelmap_size ; lbl ++ ) {
612+ int offset = seq -> s_labelmap [lbl ];
613+ if (offset >= 0 ) {
614+ assert (offset < seq -> s_used );
615+ offset2lbl [offset ] = lbl ;
616+ }
617+ }
618+
619+ for (int i = 0 ; i < seq -> s_used ; i ++ ) {
620+ int lbl = offset2lbl [i ];
621+ if (lbl >= 0 ) {
622+ assert (lbl < seq -> s_labelmap_size );
623+ jump_target_label lbl_ = {lbl };
624+ if (cfg_builder_use_label (g , lbl_ ) < 0 ) {
625+ goto error ;
604626 }
605627 }
606628 instruction * instr = & seq -> s_instrs [i ];
607- RETURN_IF_ERROR (cfg_builder_addop (g , instr -> i_opcode , instr -> i_oparg , instr -> i_loc ));
629+ int opcode = instr -> i_opcode ;
630+ int oparg = instr -> i_oparg ;
631+ if (HAS_TARGET (opcode )) {
632+ int offset = seq -> s_labelmap [oparg ];
633+ assert (offset >= 0 && offset < seq -> s_used );
634+ int lbl = offset2lbl [offset ];
635+ assert (lbl >= 0 && lbl < seq -> s_labelmap_size );
636+ oparg = lbl ;
637+ }
638+ if (cfg_builder_addop (g , opcode , oparg , instr -> i_loc ) < 0 ) {
639+ goto error ;
640+ }
608641 }
642+ PyMem_Free (offset2lbl );
643+
609644 int nblocks = 0 ;
610645 for (basicblock * b = g -> g_block_list ; b != NULL ; b = b -> b_list ) {
611646 nblocks ++ ;
@@ -615,6 +650,9 @@ instr_sequence_to_cfg(instr_sequence *seq, cfg_builder *g) {
615650 return ERROR ;
616651 }
617652 return SUCCESS ;
653+ error :
654+ PyMem_Free (offset2lbl );
655+ return ERROR ;
618656}
619657
620658
0 commit comments