114
114
import com .oracle .graal .python .runtime .GilNode ;
115
115
import com .oracle .graal .python .runtime .PosixConstants ;
116
116
import com .oracle .graal .python .runtime .PosixConstants .IntConstant ;
117
+ import com .oracle .graal .python .runtime .PosixSupport ;
117
118
import com .oracle .graal .python .runtime .PosixSupportLibrary ;
118
119
import com .oracle .graal .python .runtime .PosixSupportLibrary .Buffer ;
119
120
import com .oracle .graal .python .runtime .PosixSupportLibrary .OpenPtyResult ;
134
135
import com .oracle .truffle .api .dsl .Cached ;
135
136
import com .oracle .truffle .api .dsl .Cached .Exclusive ;
136
137
import com .oracle .truffle .api .dsl .Cached .Shared ;
138
+ import com .oracle .truffle .api .dsl .GenerateCached ;
137
139
import com .oracle .truffle .api .dsl .GenerateInline ;
138
140
import com .oracle .truffle .api .dsl .GenerateNodeFactory ;
139
141
import com .oracle .truffle .api .dsl .ImportStatic ;
@@ -533,7 +535,7 @@ private void execv(VirtualFrame frame, PosixPath path, Object argv, SequenceStor
533
535
}
534
536
Object [] opaqueArgs = new Object [args .length ];
535
537
for (int i = 0 ; i < args .length ; ++i ) {
536
- opaqueArgs [i ] = toOpaquePathNode .execute (frame , args [i ], i == 0 );
538
+ opaqueArgs [i ] = toOpaquePathNode .execute (frame , inliningTarget , args [i ], i == 0 );
537
539
}
538
540
// TODO ValueError "execv() arg 2 first element cannot be empty"
539
541
@@ -1844,7 +1846,7 @@ static Object dupAndFdopendir(VirtualFrame frame, Node inliningTarget, PosixSupp
1844
1846
}
1845
1847
1846
1848
@ SuppressWarnings ("truffle-static-method" )
1847
- abstract static class UtimeArgsToTimespecNode extends PythonBuiltinBaseNode {
1849
+ abstract static class UtimeArgsToTimespecNode extends PNodeWithRaise {
1848
1850
abstract long [] execute (VirtualFrame frame , Object times , Object ns );
1849
1851
1850
1852
Timeval [] toTimeval (VirtualFrame frame , Object times , Object ns ) {
@@ -1906,8 +1908,8 @@ private long[] convertToTimespec(VirtualFrame frame, Node inliningTarget, PTuple
1906
1908
throw timesTupleError ();
1907
1909
}
1908
1910
long [] timespec = new long [4 ];
1909
- convertToTimespecBaseNode .execute (frame , getItemNode .execute (times .getSequenceStorage (), 0 ), timespec , 0 );
1910
- convertToTimespecBaseNode .execute (frame , getItemNode .execute (times .getSequenceStorage (), 1 ), timespec , 2 );
1911
+ convertToTimespecBaseNode .execute (frame , inliningTarget , getItemNode .execute (times .getSequenceStorage (), 0 ), timespec , 0 );
1912
+ convertToTimespecBaseNode .execute (frame , inliningTarget , getItemNode .execute (times .getSequenceStorage (), 1 ), timespec , 2 );
1911
1913
return timespec ;
1912
1914
}
1913
1915
}
@@ -2667,26 +2669,23 @@ Object register(Object before, Object afterInChild, Object afterInParent) {
2667
2669
/**
2668
2670
* Helper node that accepts either str or bytes and converts it to {@code PBytes}.
2669
2671
*/
2670
- public abstract static class StringOrBytesToBytesNode extends PythonBuiltinBaseNode {
2671
- public abstract PBytes execute (Object obj );
2672
-
2673
- @ Specialization
2674
- PBytes doString (TruffleString str ,
2675
- @ Shared ("switchEncoding" ) @ Cached TruffleString .SwitchEncodingNode switchEncodingNode ,
2676
- @ Shared ("copyToByteArray" ) @ Cached TruffleString .CopyToByteArrayNode copyToByteArrayNode ) {
2672
+ @ GenerateInline
2673
+ @ GenerateCached (false )
2674
+ @ ImportStatic (PGuards .class )
2675
+ public abstract static class StringOrBytesToBytesNode extends Node {
2676
+ public abstract PBytes execute (Node inliningTarget , Object obj );
2677
+
2678
+ @ Specialization (guards = "isString(strObj)" )
2679
+ static PBytes doString (Node inliningTarget , Object strObj ,
2680
+ @ Cached CastToTruffleStringNode castToStringNode ,
2681
+ @ Cached (inline = false ) TruffleString .SwitchEncodingNode switchEncodingNode ,
2682
+ @ Cached (inline = false ) TruffleString .CopyToByteArrayNode copyToByteArrayNode ,
2683
+ @ Cached (inline = false ) PythonObjectFactory factory ) {
2684
+ TruffleString str = castToStringNode .execute (inliningTarget , strObj );
2677
2685
TruffleString utf8 = switchEncodingNode .execute (str , Encoding .UTF_8 );
2678
2686
byte [] bytes = new byte [utf8 .byteLength (Encoding .UTF_8 )];
2679
2687
copyToByteArrayNode .execute (utf8 , 0 , bytes , 0 , bytes .length , Encoding .UTF_8 );
2680
- return factory ().createBytes (bytes );
2681
- }
2682
-
2683
- @ Specialization
2684
- PBytes doPString (PString pstr ,
2685
- @ Bind ("this" ) Node inliningTarget ,
2686
- @ Cached CastToTruffleStringNode castToStringNode ,
2687
- @ Shared ("switchEncoding" ) @ Cached TruffleString .SwitchEncodingNode switchEncodingNode ,
2688
- @ Shared ("copyToByteArray" ) @ Cached TruffleString .CopyToByteArrayNode copyToByteArrayNode ) {
2689
- return doString (castToStringNode .execute (inliningTarget , pstr ), switchEncodingNode , copyToByteArrayNode );
2688
+ return factory .createBytes (bytes );
2690
2689
}
2691
2690
2692
2691
@ Specialization
@@ -2700,34 +2699,32 @@ static PBytes doBytes(PBytes bytes) {
2700
2699
* the {@link PosixSupportLibrary} in use. Basically equivalent of
2701
2700
* {@code PyUnicode_EncodeFSDefault}.
2702
2701
*/
2703
- abstract static class StringOrBytesToOpaquePathNode extends PNodeWithRaise {
2704
- abstract Object execute (Object obj );
2705
-
2706
- @ Specialization
2707
- Object doString (TruffleString str ,
2708
- @ CachedLibrary ("getContext().getPosixSupport()" ) PosixSupportLibrary posixLib ) {
2709
- return checkPath (posixLib .createPathFromString (getContext ().getPosixSupport (), str ));
2710
- }
2711
-
2712
- @ Specialization
2713
- @ SuppressWarnings ("truffle-static-method" )
2714
- Object doPString (PString pstr ,
2715
- @ Bind ("this" ) Node inliningTarget ,
2702
+ @ GenerateInline
2703
+ @ GenerateCached (false )
2704
+ @ ImportStatic (PGuards .class )
2705
+ abstract static class StringOrBytesToOpaquePathNode extends Node {
2706
+ abstract Object execute (Node inliningTarget , Object obj );
2707
+
2708
+ @ Specialization (guards = "isString(strObj)" )
2709
+ static Object doString (Node inliningTarget , Object strObj ,
2716
2710
@ Cached CastToTruffleStringNode castToStringNode ,
2717
- @ CachedLibrary ("getContext().getPosixSupport()" ) PosixSupportLibrary posixLib ) {
2718
- return doString (castToStringNode .execute (inliningTarget , pstr ), posixLib );
2711
+ @ Shared @ CachedLibrary (limit = "1" ) PosixSupportLibrary posixLib ,
2712
+ @ Shared @ Cached PRaiseNode .Lazy raiseNode ) {
2713
+ TruffleString str = castToStringNode .execute (inliningTarget , strObj );
2714
+ return checkPath (inliningTarget , posixLib .createPathFromString (PosixSupport .get (inliningTarget ), str ), raiseNode );
2719
2715
}
2720
2716
2721
2717
@ Specialization
2722
- Object doBytes (PBytes bytes ,
2723
- @ Cached BytesNodes .ToBytesNode toBytesNode ,
2724
- @ CachedLibrary ("getContext().getPosixSupport()" ) PosixSupportLibrary posixLib ) {
2725
- return checkPath (posixLib .createPathFromBytes (getContext ().getPosixSupport (), toBytesNode .execute (bytes )));
2718
+ static Object doBytes (Node inliningTarget , PBytes bytes ,
2719
+ @ Cached (inline = false ) BytesNodes .ToBytesNode toBytesNode ,
2720
+ @ Shared @ CachedLibrary (limit = "1" ) PosixSupportLibrary posixLib ,
2721
+ @ Shared @ Cached PRaiseNode .Lazy raiseNode ) {
2722
+ return checkPath (inliningTarget , posixLib .createPathFromBytes (PosixSupport .get (inliningTarget ), toBytesNode .execute (bytes )), raiseNode );
2726
2723
}
2727
2724
2728
- private Object checkPath (Object path ) {
2725
+ private static Object checkPath (Node inliningTarget , Object path , PRaiseNode . Lazy raiseNode ) {
2729
2726
if (path == null ) {
2730
- throw raise (ValueError , ErrorMessages .EMBEDDED_NULL_BYTE );
2727
+ throw raiseNode . get ( inliningTarget ). raise (ValueError , ErrorMessages .EMBEDDED_NULL_BYTE );
2731
2728
}
2732
2729
return path ;
2733
2730
}
@@ -2737,43 +2734,51 @@ private Object checkPath(Object path) {
2737
2734
* Similar to {@code PyUnicode_FSConverter}, but the actual conversion is delegated to the
2738
2735
* {@link PosixSupportLibrary} implementation.
2739
2736
*/
2740
- abstract static class ObjectToOpaquePathNode extends PNodeWithRaise {
2741
- abstract Object execute (VirtualFrame frame , Object obj , boolean checkEmpty );
2737
+ @ GenerateInline
2738
+ @ GenerateCached (false )
2739
+ abstract static class ObjectToOpaquePathNode extends Node {
2740
+ abstract Object execute (VirtualFrame frame , Node inliningTarget , Object obj , boolean checkEmpty );
2742
2741
2743
2742
@ Specialization (guards = "!checkEmpty" )
2744
- static Object noCheck (VirtualFrame frame , Object obj , @ SuppressWarnings ("unused" ) boolean checkEmpty ,
2745
- @ Bind ("this" ) Node inliningTarget ,
2743
+ static Object noCheck (VirtualFrame frame , Node inliningTarget , Object obj , @ SuppressWarnings ("unused" ) boolean checkEmpty ,
2746
2744
@ Exclusive @ Cached PyOSFSPathNode fspathNode ,
2747
2745
@ Exclusive @ Cached StringOrBytesToOpaquePathNode stringOrBytesToOpaquePathNode ) {
2748
- return stringOrBytesToOpaquePathNode .execute (fspathNode .execute (frame , inliningTarget , obj ));
2746
+ return stringOrBytesToOpaquePathNode .execute (inliningTarget , fspathNode .execute (frame , inliningTarget , obj ));
2749
2747
}
2750
2748
2751
2749
@ Specialization (guards = "checkEmpty" )
2752
- @ SuppressWarnings ("truffle-static-method" )
2753
- Object withCheck (VirtualFrame frame , Object obj , @ SuppressWarnings ("unused" ) boolean checkEmpty ,
2754
- @ Bind ("this" ) Node inliningTarget ,
2750
+ static Object withCheck (VirtualFrame frame , Node inliningTarget , Object obj , @ SuppressWarnings ("unused" ) boolean checkEmpty ,
2755
2751
@ Exclusive @ Cached PyOSFSPathNode fspathNode ,
2756
2752
@ Cached PyObjectSizeNode sizeNode ,
2757
- @ Exclusive @ Cached StringOrBytesToOpaquePathNode stringOrBytesToOpaquePathNode ) {
2753
+ @ Exclusive @ Cached StringOrBytesToOpaquePathNode stringOrBytesToOpaquePathNode ,
2754
+ @ Cached PRaiseNode .Lazy raiseNode ) {
2758
2755
Object stringOrBytes = fspathNode .execute (frame , inliningTarget , obj );
2759
2756
if (sizeNode .execute (frame , inliningTarget , obj ) == 0 ) {
2760
- throw raise (ValueError , ErrorMessages .EXECV_ARG2_FIRST_ELEMENT_CANNOT_BE_EMPTY );
2757
+ throw raiseNode . get ( inliningTarget ). raise (ValueError , ErrorMessages .EXECV_ARG2_FIRST_ELEMENT_CANNOT_BE_EMPTY );
2761
2758
}
2762
- return stringOrBytesToOpaquePathNode .execute (stringOrBytes );
2759
+ return stringOrBytesToOpaquePathNode .execute (inliningTarget , stringOrBytes );
2763
2760
}
2764
2761
}
2765
2762
2766
- abstract static class ConvertToTimespecBaseNode extends PythonBuiltinBaseNode {
2767
- abstract void execute (VirtualFrame frame , Object obj , long [] timespec , int offset );
2763
+ abstract static class ConvertToTimespecBaseNode extends Node {
2764
+ abstract void execute (VirtualFrame frame , Node inliningTarget , Object obj , long [] timespec , int offset );
2768
2765
}
2769
2766
2770
2767
/**
2771
2768
* Equivalent of {@code _PyTime_ObjectToTimespec} as used in {@code os_utime_impl}.
2772
2769
*/
2770
+ @ GenerateInline
2771
+ @ GenerateCached (false )
2772
+ @ ImportStatic (PGuards .class )
2773
2773
abstract static class ObjectToTimespecNode extends ConvertToTimespecBaseNode {
2774
2774
2775
- @ Specialization (guards = "!isNan(value)" )
2776
- void doDoubleNotNan (double value , long [] timespec , int offset ) {
2775
+ @ Specialization
2776
+ static void doDouble (Node inliningTarget , double value , long [] timespec , int offset ,
2777
+ @ Shared @ Cached PRaiseNode .Lazy raiseNode ) {
2778
+ if (Double .isNaN (value )) {
2779
+ throw raiseNode .get (inliningTarget ).raise (ValueError , ErrorMessages .INVALID_VALUE_NAN );
2780
+ }
2781
+
2777
2782
double denominator = 1000000000.0 ;
2778
2783
double floatPart = value % 1 ;
2779
2784
double intPart = value - floatPart ;
@@ -2788,26 +2793,17 @@ void doDoubleNotNan(double value, long[] timespec, int offset) {
2788
2793
}
2789
2794
assert 0.0 <= floatPart && floatPart < denominator ;
2790
2795
if (!MathGuards .fitLong (intPart )) {
2791
- throw raise (OverflowError , ErrorMessages .TIMESTAMP_OUT_OF_RANGE );
2796
+ throw raiseNode . get ( inliningTarget ). raise (OverflowError , ErrorMessages .TIMESTAMP_OUT_OF_RANGE );
2792
2797
}
2793
2798
timespec [offset ] = (long ) intPart ;
2794
2799
timespec [offset + 1 ] = (long ) floatPart ;
2795
2800
assert 0 <= timespec [offset + 1 ] && timespec [offset + 1 ] < (long ) denominator ;
2796
2801
}
2797
2802
2798
- @ Specialization (guards = "isNan(value)" )
2799
- @ SuppressWarnings ("unused" )
2800
- void doDoubleNan (double value , long [] timespec , int offset ) {
2801
- throw raise (ValueError , ErrorMessages .INVALID_VALUE_NAN );
2802
- }
2803
-
2804
2803
@ Specialization
2805
- void doPFloat (PFloat obj , long [] timespec , int offset ) {
2806
- double value = obj .getValue ();
2807
- if (Double .isNaN (value )) {
2808
- throw raise (ValueError , ErrorMessages .INVALID_VALUE_NAN );
2809
- }
2810
- doDoubleNotNan (value , timespec , offset );
2804
+ static void doPFloat (Node inliningTarget , PFloat obj , long [] timespec , int offset ,
2805
+ @ Shared @ Cached PRaiseNode .Lazy raiseNode ) {
2806
+ doDouble (inliningTarget , obj .getValue (), timespec , offset , raiseNode );
2811
2807
}
2812
2808
2813
2809
@ Specialization
@@ -2823,26 +2819,24 @@ static void doLong(long value, long[] timespec, int offset) {
2823
2819
}
2824
2820
2825
2821
@ Specialization (guards = {"!isDouble(value)" , "!isPFloat(value)" , "!isInteger(value)" })
2826
- void doGeneric (VirtualFrame frame , Object value , long [] timespec , int offset ,
2827
- @ Bind ( "this" ) Node inliningTarget ,
2828
- @ Cached PyLongAsLongAndOverflowNode asLongNode ) {
2822
+ static void doGeneric (VirtualFrame frame , Node inliningTarget , Object value , long [] timespec , int offset ,
2823
+ @ Cached PyLongAsLongAndOverflowNode asLongNode ,
2824
+ @ Shared @ Cached PRaiseNode . Lazy raiseNode ) {
2829
2825
try {
2830
2826
timespec [offset ] = asLongNode .execute (frame , inliningTarget , value );
2831
2827
} catch (OverflowException e ) {
2832
- throw raise (OverflowError , ErrorMessages .TIMESTAMP_OUT_OF_RANGE );
2828
+ throw raiseNode . get ( inliningTarget ). raise (OverflowError , ErrorMessages .TIMESTAMP_OUT_OF_RANGE );
2833
2829
}
2834
2830
timespec [offset + 1 ] = 0 ;
2835
2831
}
2836
-
2837
- protected static boolean isNan (double value ) {
2838
- return Double .isNaN (value );
2839
- }
2840
2832
}
2841
2833
2842
2834
/**
2843
2835
* Equivalent of {@code split_py_long_to_s_and_ns} as used in {@code os_utime_impl}.
2844
2836
*/
2845
- @ ImportStatic (BinaryArithmetic .class )
2837
+ @ GenerateInline
2838
+ @ GenerateCached (false )
2839
+ @ ImportStatic ({BinaryArithmetic .class , PGuards .class })
2846
2840
abstract static class SplitLongToSAndNsNode extends ConvertToTimespecBaseNode {
2847
2841
2848
2842
private static final long BILLION = 1000000000 ;
@@ -2859,11 +2853,10 @@ static void doLong(long value, long[] timespec, int offset) {
2859
2853
}
2860
2854
2861
2855
@ Specialization (guards = {"!isInteger(value)" })
2862
- static void doGeneric (VirtualFrame frame , Object value , long [] timespec , int offset ,
2863
- @ Bind ("this" ) Node inliningTarget ,
2864
- @ Cached ("DivMod.create()" ) BinaryOpNode callDivmod ,
2856
+ static void doGeneric (VirtualFrame frame , Node inliningTarget , Object value , long [] timespec , int offset ,
2857
+ @ Cached (value = "DivMod.create()" , inline = false ) BinaryOpNode callDivmod ,
2865
2858
@ Cached LenNode lenNode ,
2866
- @ Cached ("createNotNormalized()" ) GetItemNode getItemNode ,
2859
+ @ Cached (value = "createNotNormalized()" , inline = false ) GetItemNode getItemNode ,
2867
2860
@ Cached PyLongAsLongNode asLongNode ,
2868
2861
@ Cached PRaiseNode .Lazy raiseNode ) {
2869
2862
Object divmod = callDivmod .executeObject (frame , value , BILLION );
@@ -2923,7 +2916,7 @@ static PBytes convert(VirtualFrame frame, Object value,
2923
2916
@ Bind ("this" ) Node inliningTarget ,
2924
2917
@ Cached PyOSFSPathNode fspathNode ,
2925
2918
@ Cached StringOrBytesToBytesNode stringOrBytesToBytesNode ) {
2926
- return stringOrBytesToBytesNode .execute (fspathNode .execute (frame , inliningTarget , value ));
2919
+ return stringOrBytesToBytesNode .execute (inliningTarget , fspathNode .execute (frame , inliningTarget , value ));
2927
2920
}
2928
2921
2929
2922
@ ClinicConverterFactory
0 commit comments