@@ -595,17 +595,52 @@ static int
595
595
instr_sequence_to_cfg (instr_sequence * seq , cfg_builder * g ) {
596
596
memset (g , 0 , sizeof (cfg_builder ));
597
597
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
+ }
599
608
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 ;
604
626
}
605
627
}
606
628
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
+ }
608
641
}
642
+ PyMem_Free (offset2lbl );
643
+
609
644
int nblocks = 0 ;
610
645
for (basicblock * b = g -> g_block_list ; b != NULL ; b = b -> b_list ) {
611
646
nblocks ++ ;
@@ -615,6 +650,9 @@ instr_sequence_to_cfg(instr_sequence *seq, cfg_builder *g) {
615
650
return ERROR ;
616
651
}
617
652
return SUCCESS ;
653
+ error :
654
+ PyMem_Free (offset2lbl );
655
+ return ERROR ;
618
656
}
619
657
620
658
0 commit comments