48
48
import java .util .List ;
49
49
import java .util .Objects ;
50
50
51
+ import com .oracle .graal .python .builtins .PythonBuiltinClassType ;
51
52
import com .oracle .graal .python .builtins .objects .bytes .BytesUtils ;
52
53
import com .oracle .graal .python .builtins .objects .code .PCode ;
53
54
import com .oracle .graal .python .builtins .objects .str .StringNodes ;
54
55
import com .oracle .graal .python .compiler .OpCodes .CollectionBits ;
56
+ import com .oracle .graal .python .nodes .ErrorMessages ;
57
+ import com .oracle .graal .python .nodes .PRaiseNode ;
55
58
import com .oracle .graal .python .util .PythonUtils ;
56
59
import com .oracle .truffle .api .CompilerDirectives ;
57
60
import com .oracle .truffle .api .CompilerDirectives .CompilationFinal ;
@@ -536,7 +539,10 @@ public int lineToBci(int line) {
536
539
if (startLine == line ) {
537
540
return 0 ;
538
541
}
539
- // todo look into instrumentation support
542
+ if ((flags & PCode .CO_GRAALPYHON_MODULE ) != 0 && line < startLine ) {
543
+ // allow jump to the first line of a file, even if it is a comment
544
+ return 0 ;
545
+ }
540
546
int [] map = getSourceMap ().startLineMap ;
541
547
int bestBci = -1 ;
542
548
int lineDiff = Integer .MAX_VALUE ;
@@ -584,7 +590,7 @@ private void setNextStack(ArrayDeque<Integer> todo, List<ArrayList<StackItem>> s
584
590
stacks .set (target , value );
585
591
todo .addLast (target );
586
592
} else {
587
- assert value .equals (blocksAtTarget ) : "found conflicting stacks depending on code path: " + this .name ;
593
+ assert value .equals (blocksAtTarget ) : "found conflicting stacks depending on code path: " + this .name + " \t at " + target ;
588
594
}
589
595
}
590
596
@@ -595,22 +601,16 @@ private static ArrayList<StackItem> popStack(ArrayList<StackItem> blocks) {
595
601
}
596
602
597
603
// returns null if the jump is fine
598
- public String checkJump (int from , int to ) {
599
- List <ArrayList <StackItem >> blocks = computeStackElems ();
600
- ArrayList <StackItem > blkFrom = blocks .get (from );
601
- System .out .println (this );
602
-
603
- iterateBytecode (code , (bci , op , oparg , following ) -> {
604
- System .out .println (bci + "\t " +
605
- op .getNumberOfProducedStackItems (oparg , following , false ) + "\t " +
606
- op .getNumberOfConsumedStackItems (oparg , following , false ) + "\t " + op + "\t " +
607
- blocks .get (bci ));
608
- });
609
-
610
- // todo these should be exceptions
611
- assert blkFrom != null : "Unreachable origin" ;
612
- ArrayList <StackItem > blkTo = blocks .get (to );
613
- assert blkTo != null : "Unreachable target" ;
604
+ public String checkJump (List <ArrayList <StackItem >> stackElems , int from , int to ) {
605
+ ArrayList <StackItem > blkFrom = stackElems .get (from );
606
+ if (blkFrom == null ) {
607
+ // this should not happen
608
+ PRaiseNode .getUncached ().raise (PythonBuiltinClassType .ValueError , ErrorMessages .LINE_D_COMES_BEFORE_THE_CURRENT_CODE_BLOCK , bciToLine (from ));
609
+ }
610
+ ArrayList <StackItem > blkTo = stackElems .get (to );
611
+ if (blkTo == null ) {
612
+ PRaiseNode .getUncached ().raise (PythonBuiltinClassType .ValueError , ErrorMessages .LINE_D_COMES_AFTER_THE_CURRENT_CODE_BLOCK , bciToLine (from ));
613
+ }
614
614
if (blkTo .size () > blkFrom .size ()) {
615
615
return blkTo .get (blkTo .size () - 1 ).error ;
616
616
}
@@ -622,7 +622,7 @@ public String checkJump(int from, int to) {
622
622
return null ;
623
623
}
624
624
625
- private List <ArrayList <StackItem >> computeStackElems () {
625
+ public List <ArrayList <StackItem >> computeStackElems () {
626
626
List <ArrayList <StackItem >> blocks = new ArrayList <>(Collections .nCopies (code .length + 1 , null ));
627
627
blocks .set (0 , new ArrayList <>());
628
628
ArrayDeque <Integer > todo = new ArrayDeque <>();
@@ -649,8 +649,12 @@ private List<ArrayList<StackItem>> computeStackElems() {
649
649
next = StackItem .Iterable .push (popStack (blocks .get (bci )));
650
650
setNextStack (todo , blocks , bci + 1 , next );
651
651
break ;
652
+ case FOR_ITER :
653
+ setNextStack (todo , blocks , op .getNextBci (bci , oparg , false ), StackItem .Object .push (next ));
654
+ setNextStack (todo , blocks , op .getNextBci (bci , oparg , true ), popStack (next ));
655
+ break ;
652
656
case PUSH_EXC_INFO :
653
- next = StackItem .Except .push (blocks .get (bci ));
657
+ next = StackItem .Except .push (StackItem . Object . push ( popStack ( blocks .get (bci )) ));
654
658
setNextStack (todo , blocks , bci + 1 , next );
655
659
break ;
656
660
case MATCH_EXC_OR_JUMP :
@@ -732,56 +736,6 @@ private void handleGeneralOp(List<ArrayList<StackItem>> blocks, ArrayDeque<Integ
732
736
}
733
737
}
734
738
735
- @ CompilerDirectives .TruffleBoundary
736
- public int [] computeStackLevels () {
737
- int [] stackLevels = new int [code .length ];
738
- Arrays .fill (stackLevels , -1 );
739
- // stackLevels has the stack depth before the corresponding opcode executes
740
- stackLevels [0 ] = 0 ;
741
- // deque of bci
742
- ArrayDeque <Integer > todo = new ArrayDeque <>();
743
- todo .addFirst (0 );
744
- for (int i = 0 ; i < exceptionHandlerRanges .length ; i += 4 ) {
745
- int handler = exceptionHandlerRanges [i + 2 ];
746
- int stackAtHandler = exceptionHandlerRanges [i + 3 ];
747
- // stack at handler + the exception
748
- stackLevels [handler ] = stackAtHandler + 1 ;
749
- todo .addFirst (handler );
750
- }
751
- while (!todo .isEmpty ()) {
752
- int bci = todo .removeLast ();
753
- int stackHere = stackLevels [bci ];
754
- assert stackHere >= 0 ;
755
- opCodeAt (code , bci , (ignored , op , oparg , followingArgs ) -> {
756
- assert stackHere >= op .getNumberOfConsumedStackItems (oparg , followingArgs , true ) : "failed at:" + op + ":" + bci ;
757
- assert stackHere >= op .getNumberOfConsumedStackItems (oparg , followingArgs , false ) : "failed at:" + op + ":" + bci ;
758
- int stackWJump = op .getStackEffect (oparg , followingArgs , true );
759
- int stackWOJump = op .getStackEffect (oparg , followingArgs , false );
760
- int bciWJump = op .getNextBci (bci , oparg , true );
761
- int bciWOJump = op .getNextBci (bci , oparg , false );
762
- if (bciWJump == -1 ) {
763
- assert bciWOJump == bciWJump ;
764
- return ;
765
- }
766
- if (stackLevels [bciWJump ] < 0 ) {
767
- stackLevels [bciWJump ] = stackHere + stackWJump ;
768
- todo .addFirst (bciWJump );
769
- } else {
770
- assert stackLevels [bciWJump ] == stackHere + stackWJump ;
771
- }
772
- if (bciWJump != bciWOJump ) {
773
- if (stackLevels [bciWOJump ] < 0 ) {
774
- stackLevels [bciWOJump ] = stackHere + stackWOJump ;
775
- todo .addFirst (bciWOJump );
776
- } else {
777
- assert stackLevels [bciWOJump ] == stackHere + stackWOJump ;
778
- }
779
- }
780
- });
781
- }
782
- return stackLevels ;
783
- }
784
-
785
739
@ FunctionalInterface
786
740
public interface BytecodeAction {
787
741
void run (int bci , OpCodes op , int oparg , byte [] followingArgs );
0 commit comments