160160import com .oracle .graal .python .nodes .object .IsBuiltinClassProfile ;
161161import com .oracle .graal .python .nodes .truffle .PythonArithmeticTypes ;
162162import com .oracle .graal .python .nodes .util .CannotCastException ;
163+ import com .oracle .graal .python .nodes .util .CastToJavaIntExactNode ;
163164import com .oracle .graal .python .nodes .util .CastToJavaLongExactNode ;
164165import com .oracle .graal .python .nodes .util .CastToJavaStringNode ;
165166import com .oracle .graal .python .runtime .PythonContext ;
@@ -740,6 +741,28 @@ protected boolean shouldStripLeadingWhitespace() {
740741 @ GenerateNodeFactory
741742 @ TypeSystemReference (PythonArithmeticTypes .class )
742743 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+
743766 /**
744767 * Decides wether this node should attempt to map the filename to a URI for the benefit of
745768 * Truffle tooling
@@ -762,7 +785,7 @@ public CompileNode() {
762785 @ SuppressWarnings ("unused" )
763786 @ Specialization
764787 @ 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 ) {
766789 String code = expression ;
767790 PythonContext context = getContext ();
768791 ParserMode pm ;
@@ -800,6 +823,7 @@ PCode compile(String expression, String filename, String mode, Object kwFlags, O
800823 @ Specialization (limit = "3" )
801824 PCode generic (VirtualFrame frame , Object wSource , Object wFilename , Object wMode , Object kwFlags , Object kwDontInherit , Object kwOptimize ,
802825 @ Cached CastToJavaStringNode castStr ,
826+ @ Cached CastToJavaIntExactNode castInt ,
803827 @ Cached CodecsModuleBuiltins .HandleDecodingErrorNode handleDecodingErrorNode ,
804828 @ CachedLibrary ("wSource" ) InteropLibrary interopLib ,
805829 @ CachedLibrary (limit = "4" ) PythonObjectLibrary lib ) {
@@ -813,8 +837,33 @@ PCode generic(VirtualFrame frame, Object wSource, Object wFilename, Object wMode
813837 } catch (CannotCastException e ) {
814838 throw raise (TypeError , ErrorMessages .ARG_S_MUST_BE_S_NOT_P , "compile()" , "mode" , "str" , wMode );
815839 }
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+ }
816862 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 );
818867 }
819868
820869 // modeled after _Py_SourceAsString
0 commit comments