160
160
import com .oracle .graal .python .nodes .object .IsBuiltinClassProfile ;
161
161
import com .oracle .graal .python .nodes .truffle .PythonArithmeticTypes ;
162
162
import com .oracle .graal .python .nodes .util .CannotCastException ;
163
+ import com .oracle .graal .python .nodes .util .CastToJavaIntExactNode ;
163
164
import com .oracle .graal .python .nodes .util .CastToJavaLongExactNode ;
164
165
import com .oracle .graal .python .nodes .util .CastToJavaStringNode ;
165
166
import com .oracle .graal .python .runtime .PythonContext ;
@@ -740,6 +741,28 @@ protected boolean shouldStripLeadingWhitespace() {
740
741
@ GenerateNodeFactory
741
742
@ TypeSystemReference (PythonArithmeticTypes .class )
742
743
public abstract static class CompileNode extends PythonBuiltinNode {
744
+
745
+ // code.h
746
+ private static final int CO_NESTED = 0x0010 ;
747
+ private static final int CO_FUTURE_DIVISION = 0x20000 ;
748
+ private static final int CO_FUTURE_ABSOLUTE_IMPORT = 0x40000 ;
749
+ private static final int CO_FUTURE_WITH_STATEMENT = 0x80000 ;
750
+ private static final int CO_FUTURE_PRINT_FUNCTION = 0x100000 ;
751
+ private static final int CO_FUTURE_UNICODE_LITERALS = 0x200000 ;
752
+
753
+ private static final int CO_FUTURE_BARRY_AS_BDFL = 0x400000 ;
754
+ private static final int CO_FUTURE_GENERATOR_STOP = 0x800000 ;
755
+ private static final int CO_FUTURE_ANNOTATIONS = 0x1000000 ;
756
+
757
+ // compile.h
758
+ private static final int PyCF_MASK = CO_FUTURE_DIVISION | CO_FUTURE_ABSOLUTE_IMPORT | CO_FUTURE_WITH_STATEMENT | CO_FUTURE_PRINT_FUNCTION | CO_FUTURE_UNICODE_LITERALS |
759
+ CO_FUTURE_BARRY_AS_BDFL | CO_FUTURE_GENERATOR_STOP | CO_FUTURE_ANNOTATIONS ;
760
+ private static final int PyCF_MASK_OBSOLETE = CO_NESTED ;
761
+
762
+ private static final int PyCF_DONT_IMPLY_DEDENT = 0x0200 ;
763
+ private static final int PyCF_ONLY_AST = 0x0400 ;
764
+ private static final int PyCF_TYPE_COMMENTS = 0x1000 ;
765
+
743
766
/**
744
767
* Decides wether this node should attempt to map the filename to a URI for the benefit of
745
768
* Truffle tooling
@@ -762,7 +785,7 @@ public CompileNode() {
762
785
@ SuppressWarnings ("unused" )
763
786
@ Specialization
764
787
@ TruffleBoundary
765
- PCode compile (String expression , String filename , String mode , Object kwFlags , Object kwDontInherit , Object kwOptimize ) {
788
+ PCode compile (String expression , String filename , String mode , int kwFlags , Object kwDontInherit , int kwOptimize ) {
766
789
String code = expression ;
767
790
PythonContext context = getContext ();
768
791
ParserMode pm ;
@@ -800,6 +823,7 @@ PCode compile(String expression, String filename, String mode, Object kwFlags, O
800
823
@ Specialization (limit = "3" )
801
824
PCode generic (VirtualFrame frame , Object wSource , Object wFilename , Object wMode , Object kwFlags , Object kwDontInherit , Object kwOptimize ,
802
825
@ Cached CastToJavaStringNode castStr ,
826
+ @ Cached CastToJavaIntExactNode castInt ,
803
827
@ Cached CodecsModuleBuiltins .HandleDecodingErrorNode handleDecodingErrorNode ,
804
828
@ CachedLibrary ("wSource" ) InteropLibrary interopLib ,
805
829
@ CachedLibrary (limit = "4" ) PythonObjectLibrary lib ) {
@@ -813,8 +837,33 @@ PCode generic(VirtualFrame frame, Object wSource, Object wFilename, Object wMode
813
837
} catch (CannotCastException e ) {
814
838
throw raise (TypeError , ErrorMessages .ARG_S_MUST_BE_S_NOT_P , "compile()" , "mode" , "str" , wMode );
815
839
}
840
+ int flags = 0 ;
841
+ if (kwFlags != PNone .NO_VALUE ) {
842
+ try {
843
+ flags = castInt .execute (kwFlags );
844
+ } catch (CannotCastException e ) {
845
+ throw raise (TypeError , ErrorMessages .INTEGER_REQUIRED_GOT , kwFlags );
846
+ }
847
+ if ((flags & ~(PyCF_MASK | PyCF_MASK_OBSOLETE | PyCF_DONT_IMPLY_DEDENT | PyCF_ONLY_AST | PyCF_TYPE_COMMENTS )) > 0 ) {
848
+ throw raise (ValueError , "compile(): unrecognised flags" );
849
+ }
850
+ }
851
+ int optimize = 0 ;
852
+ if (kwOptimize != PNone .NO_VALUE ) {
853
+ try {
854
+ optimize = castInt .execute (kwOptimize );
855
+ } catch (CannotCastException e ) {
856
+ throw raise (TypeError , ErrorMessages .INTEGER_REQUIRED_GOT , kwFlags );
857
+ }
858
+ if (optimize < -1 || optimize > 2 ) {
859
+ throw raise (TypeError , "compile(): invalid optimize value" , kwOptimize );
860
+ }
861
+ }
816
862
String source = sourceAsString (wSource , filename , interopLib , lib , handleDecodingErrorNode );
817
- return compile (source , filename , mode , kwFlags , kwDontInherit , kwOptimize );
863
+ if (source .indexOf (0 ) > -1 ) {
864
+ throw raise (ValueError , "source code string cannot contain null bytes" );
865
+ }
866
+ return compile (source , filename , mode , flags , kwDontInherit , optimize );
818
867
}
819
868
820
869
// modeled after _Py_SourceAsString
0 commit comments