36
36
import static com .oracle .graal .python .nodes .BuiltinNames .DIR ;
37
37
import static com .oracle .graal .python .nodes .BuiltinNames .DIVMOD ;
38
38
import static com .oracle .graal .python .nodes .BuiltinNames .EVAL ;
39
+ import static com .oracle .graal .python .nodes .BuiltinNames .EXEC ;
39
40
import static com .oracle .graal .python .nodes .BuiltinNames .GETATTR ;
40
41
import static com .oracle .graal .python .nodes .BuiltinNames .HASH ;
41
42
import static com .oracle .graal .python .nodes .BuiltinNames .ID ;
173
174
import com .oracle .truffle .api .frame .FrameSlot ;
174
175
import com .oracle .truffle .api .frame .VirtualFrame ;
175
176
import com .oracle .truffle .api .nodes .ExplodeLoop ;
177
+ import com .oracle .truffle .api .nodes .IndirectCallNode ;
176
178
import com .oracle .truffle .api .nodes .Node ;
177
179
import com .oracle .truffle .api .nodes .NodeUtil ;
178
180
import com .oracle .truffle .api .nodes .NodeVisitor ;
@@ -596,31 +598,61 @@ private static Object evalNode(RootCallTarget callTarget, PythonObject globals,
596
598
}
597
599
}
598
600
601
+ @ Builtin (name = EXEC , fixedNumOfPositionalArgs = 1 , parameterNames = {"source" }, keywordArguments = {"globals" , "locals" })
602
+ @ GenerateNodeFactory
603
+ abstract static class ExecNode extends PythonBuiltinNode {
604
+ @ Child CompileNode compileNode = CompileNode .create ();
605
+ @ Child IndirectCallNode indirectCallNode = IndirectCallNode .create ();
606
+
607
+ @ Specialization (guards = {"isNoValue(globals)" , "isNoValue(locals)" })
608
+ PNone execDefault (VirtualFrame frame , Object source , @ SuppressWarnings ("unused" ) PNone globals , @ SuppressWarnings ("unused" ) PNone locals ,
609
+ @ Cached ("create()" ) ReadCallerFrameNode readCallerFrameNode ) {
610
+ PCode code = compileNode .execute (source , "exec" , "exec" , 0 , false , -1 );
611
+ Frame callerFrame = readCallerFrameNode .executeWith (frame );
612
+ Object [] args = PArguments .create ();
613
+ PArguments .setGlobals (args , PArguments .getGlobals (callerFrame ));
614
+ PArguments .setClosure (args , PArguments .getClosure (callerFrame ));
615
+ indirectCallNode .call (code .getRootCallTarget (), args );
616
+ return PNone .NO_VALUE ;
617
+ }
618
+
619
+ @ Specialization (guards = {"isNoValue(locals)" })
620
+ PNone execDefault (Object source , PDict globals , @ SuppressWarnings ("unused" ) PNone locals ) {
621
+ PCode code = compileNode .execute (source , "exec" , "exec" , 0 , false , -1 );
622
+ Object [] args = PArguments .create ();
623
+ PArguments .setGlobals (args , globals );
624
+ // If locals are not given, they default to the globals, so we don't need the caller
625
+ // frame's closure at all
626
+ indirectCallNode .call (code .getRootCallTarget (), args );
627
+ return PNone .NO_VALUE ;
628
+ }
629
+ }
630
+
599
631
// compile(source, filename, mode, flags=0, dont_inherit=False, optimize=-1)
600
632
@ Builtin (name = COMPILE , fixedNumOfPositionalArgs = 3 , keywordArguments = {"flags" , "dont_inherit" , "optimize" })
601
633
@ GenerateNodeFactory
602
634
@ TypeSystemReference (PythonArithmeticTypes .class )
603
635
public abstract static class CompileNode extends PythonBuiltinNode {
604
636
605
- public abstract Object execute (Object source , String filename , String mode , Object kwFlags , Object kwDontInherit , Object kwOptimize );
637
+ public abstract PCode execute (Object source , String filename , String mode , Object kwFlags , Object kwDontInherit , Object kwOptimize );
606
638
607
639
@ Specialization
608
640
@ TruffleBoundary
609
- Object compile (PBytes source , String filename , String mode , Object kwFlags , Object kwDontInherit , Object kwOptimize ,
641
+ PCode compile (PBytes source , String filename , String mode , Object kwFlags , Object kwDontInherit , Object kwOptimize ,
610
642
@ Cached ("create()" ) BytesNodes .ToBytesNode toBytesNode ) {
611
643
return compile (new String (toBytesNode .execute (source )), filename , mode , kwFlags , kwDontInherit , kwOptimize );
612
644
}
613
645
614
646
@ Specialization
615
647
@ TruffleBoundary
616
- Object compile (OpaqueBytes source , String filename , String mode , Object kwFlags , Object kwDontInherit , Object kwOptimize ) {
648
+ PCode compile (OpaqueBytes source , String filename , String mode , Object kwFlags , Object kwDontInherit , Object kwOptimize ) {
617
649
return compile (new String (source .getBytes ()), filename , mode , kwFlags , kwDontInherit , kwOptimize );
618
650
}
619
651
620
652
@ SuppressWarnings ("unused" )
621
653
@ Specialization
622
654
@ TruffleBoundary
623
- Object compile (String expression , String filename , String mode , Object kwFlags , Object kwDontInherit , Object kwOptimize ) {
655
+ PCode compile (String expression , String filename , String mode , Object kwFlags , Object kwDontInherit , Object kwOptimize ) {
624
656
Source source = PythonLanguage .newSource (getContext (), expression , filename );
625
657
ParserMode pm ;
626
658
if (mode .equals ("exec" )) {
@@ -642,7 +674,7 @@ Object compile(String expression, String filename, String mode, Object kwFlags,
642
674
643
675
@ SuppressWarnings ("unused" )
644
676
@ Specialization
645
- Object compile (PCode code , String filename , String mode , Object flags , Object dontInherit , Object optimize ) {
677
+ PCode compile (PCode code , String filename , String mode , Object flags , Object dontInherit , Object optimize ) {
646
678
return code ;
647
679
}
648
680
0 commit comments