|
159 | 159 | import com.oracle.graal.python.builtins.objects.list.PList;
|
160 | 160 | import com.oracle.graal.python.builtins.objects.module.PythonModule;
|
161 | 161 | import com.oracle.graal.python.builtins.objects.object.ObjectNodes;
|
162 |
| -import com.oracle.graal.python.builtins.objects.object.PythonObject; |
163 | 162 | import com.oracle.graal.python.builtins.objects.tuple.PTuple;
|
164 | 163 | import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot;
|
165 | 164 | import com.oracle.graal.python.builtins.objects.type.TpSlots;
|
@@ -785,194 +784,116 @@ static Object doObject(VirtualFrame frame, Object a, Object b,
|
785 | 784 | }
|
786 | 785 | }
|
787 | 786 |
|
788 |
| - // eval(expression, globals=None, locals=None) |
789 |
| - @Builtin(name = J_EVAL, minNumOfPositionalArgs = 1, parameterNames = {"expression", "globals", "locals"}) |
790 |
| - @GenerateNodeFactory |
791 |
| - public abstract static class EvalNode extends PythonBuiltinNode { |
792 |
| - @Child protected CompileNode compileNode; |
793 |
| - @Child private GetOrCreateDictNode getOrCreateDictNode; |
794 |
| - |
795 |
| - final void assertNoFreeVars(Node inliningTarget, PCode code, PRaiseNode raiseNode) { |
796 |
| - Object[] freeVars = code.getFreeVars(); |
797 |
| - if (freeVars.length > 0) { |
798 |
| - throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.CODE_OBJ_NO_FREE_VARIABLES, getMode()); |
799 |
| - } |
800 |
| - } |
801 |
| - |
802 |
| - protected TruffleString getMode() { |
803 |
| - return T_EVAL; |
804 |
| - } |
805 |
| - |
806 |
| - static boolean isMapping(Node inliningTarget, PyMappingCheckNode mappingCheckNode, Object object) { |
807 |
| - return mappingCheckNode.execute(inliningTarget, object); |
808 |
| - } |
809 |
| - |
810 |
| - static boolean isAnyNone(Object object) { |
811 |
| - return object instanceof PNone; |
812 |
| - } |
813 |
| - |
814 |
| - final PCode createAndCheckCode(VirtualFrame frame, Node inliningTarget, Object source, PRaiseNode raiseNode) { |
815 |
| - PCode code = getCompileNode().compile(frame, source, T_STRING_SOURCE, getMode(), -1, -1); |
816 |
| - assertNoFreeVars(inliningTarget, code, raiseNode); |
817 |
| - return code; |
818 |
| - } |
819 |
| - |
820 |
| - private static void inheritGlobals(PFrame callerFrame, Object[] args) { |
821 |
| - PArguments.setGlobals(args, callerFrame.getGlobals()); |
822 |
| - } |
823 |
| - |
824 |
| - private static void inheritLocals(Node inliningTarget, PFrame callerFrame, Object[] args, GetFrameLocalsNode getFrameLocalsNode) { |
825 |
| - Object callerLocals = getFrameLocalsNode.execute(inliningTarget, callerFrame); |
826 |
| - setCustomLocals(args, callerLocals); |
827 |
| - } |
828 |
| - |
829 |
| - private static void setCustomLocals(Object[] args, Object locals) { |
830 |
| - PArguments.setSpecialArgument(args, locals); |
831 |
| - } |
832 |
| - |
833 |
| - private void setBuiltinsInGlobals(VirtualFrame frame, Node inliningTarget, PDict globals, HashingCollectionNodes.SetItemNode setBuiltins, PythonModule builtins) { |
834 |
| - if (builtins != null) { |
835 |
| - PDict builtinsDict = getOrCreateDictNode(builtins); |
836 |
| - setBuiltins.execute(frame, inliningTarget, globals, T___BUILTINS__, builtinsDict); |
837 |
| - } else { |
838 |
| - // This happens during context initialization |
839 |
| - return; |
840 |
| - } |
841 |
| - } |
842 |
| - |
843 |
| - private void setCustomGlobals(VirtualFrame frame, Node inliningTarget, PDict globals, HashingCollectionNodes.SetItemNode setBuiltins, Object[] args) { |
844 |
| - PythonModule builtins = getContext().getBuiltins(); |
845 |
| - setBuiltinsInGlobals(frame, inliningTarget, globals, setBuiltins, builtins); |
846 |
| - PArguments.setGlobals(args, globals); |
847 |
| - } |
| 787 | + @GenerateInline |
| 788 | + @GenerateCached(false) |
| 789 | + abstract static class CreateEvalExecArgumentsNode extends Node { |
| 790 | + public abstract Object[] execute(VirtualFrame frame, Node inliningTarget, Object globals, Object locals, TruffleString mode); |
848 | 791 |
|
849 | 792 | @Specialization
|
850 |
| - @SuppressWarnings("truffle-static-method") |
851 |
| - Object execInheritGlobalsInheritLocals(VirtualFrame frame, Object source, @SuppressWarnings("unused") PNone globals, @SuppressWarnings("unused") PNone locals, |
852 |
| - @Bind("this") Node inliningTarget, |
| 793 | + static Object[] inheritGlobals(VirtualFrame frame, Node inliningTarget, @SuppressWarnings("unused") PNone globals, Object locals, TruffleString mode, |
853 | 794 | @Exclusive @Cached ReadCallerFrameNode readCallerFrameNode,
|
854 |
| - @Exclusive @Cached CodeNodes.GetCodeCallTargetNode getCt, |
855 |
| - @Cached GetFrameLocalsNode getFrameLocalsNode, |
856 |
| - @Shared @Cached CallDispatchers.SimpleIndirectInvokeNode invoke, |
| 795 | + @Exclusive @Cached InlinedConditionProfile haveLocals, |
| 796 | + @Exclusive @Cached PyMappingCheckNode mappingCheckNode, |
| 797 | + @Exclusive @Cached GetFrameLocalsNode getFrameLocalsNode, |
857 | 798 | @Exclusive @Cached PRaiseNode raiseNode) {
|
858 |
| - PCode code = createAndCheckCode(frame, inliningTarget, source, raiseNode); |
859 | 799 | PFrame callerFrame = readCallerFrameNode.executeWith(frame, 0);
|
860 | 800 | Object[] args = PArguments.create();
|
861 |
| - inheritGlobals(callerFrame, args); |
862 |
| - inheritLocals(inliningTarget, callerFrame, args, getFrameLocalsNode); |
863 |
| - |
864 |
| - return invoke.execute(frame, inliningTarget, getCt.execute(inliningTarget, code), args); |
| 801 | + PArguments.setGlobals(args, callerFrame.getGlobals()); |
| 802 | + if (haveLocals.profile(inliningTarget, locals instanceof PNone)) { |
| 803 | + Object callerLocals = getFrameLocalsNode.execute(inliningTarget, callerFrame); |
| 804 | + setCustomLocals(args, callerLocals); |
| 805 | + } else { |
| 806 | + if (!mappingCheckNode.execute(inliningTarget, locals)) { |
| 807 | + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.LOCALS_MUST_BE_MAPPING, mode, locals); |
| 808 | + } |
| 809 | + setCustomLocals(args, locals); |
| 810 | + } |
| 811 | + return args; |
865 | 812 | }
|
866 | 813 |
|
867 | 814 | @Specialization
|
868 |
| - Object execCustomGlobalsGlobalLocals(VirtualFrame frame, Object source, PDict globals, @SuppressWarnings("unused") PNone locals, |
869 |
| - @Bind("this") Node inliningTarget, |
870 |
| - @Shared @Cached HashingCollectionNodes.SetItemNode setBuiltins, |
871 |
| - @Shared("getCt") @Cached CodeNodes.GetCodeCallTargetNode getCt, |
872 |
| - @Shared @Cached CallDispatchers.SimpleIndirectInvokeNode invoke, |
873 |
| - @Shared @Cached PRaiseNode raiseNode) { |
874 |
| - PCode code = createAndCheckCode(frame, inliningTarget, source, raiseNode); |
| 815 | + static Object[] customGlobals(VirtualFrame frame, Node inliningTarget, PDict globals, Object locals, TruffleString mode, |
| 816 | + @Bind PythonContext context, |
| 817 | + @Exclusive @Cached InlinedConditionProfile haveLocals, |
| 818 | + @Exclusive @Cached PyMappingCheckNode mappingCheckNode, |
| 819 | + @Exclusive @Cached GetOrCreateDictNode getOrCreateDictNode, |
| 820 | + @Exclusive @Cached HashingCollectionNodes.SetItemNode setBuiltins, |
| 821 | + @Exclusive @Cached PRaiseNode raiseNode) { |
875 | 822 | Object[] args = PArguments.create();
|
876 |
| - setCustomGlobals(frame, inliningTarget, globals, setBuiltins, args); |
877 |
| - setCustomLocals(args, globals); |
878 |
| - RootCallTarget rootCallTarget = getCt.execute(inliningTarget, code); |
879 |
| - if (rootCallTarget == null) { |
880 |
| - throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.CANNOT_CREATE_CALL_TARGET, code); |
| 823 | + PythonModule builtins = context.getBuiltins(); |
| 824 | + // Builtins may be null during context initialization |
| 825 | + if (builtins != null) { |
| 826 | + PDict builtinsDict = getOrCreateDictNode.execute(inliningTarget, builtins); |
| 827 | + setBuiltins.execute(frame, inliningTarget, globals, T___BUILTINS__, builtinsDict); |
| 828 | + } |
| 829 | + PArguments.setGlobals(args, globals); |
| 830 | + if (haveLocals.profile(inliningTarget, locals instanceof PNone)) { |
| 831 | + setCustomLocals(args, globals); |
| 832 | + } else { |
| 833 | + if (!mappingCheckNode.execute(inliningTarget, locals)) { |
| 834 | + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.LOCALS_MUST_BE_MAPPING, mode, locals); |
| 835 | + } |
| 836 | + setCustomLocals(args, locals); |
881 | 837 | }
|
882 | 838 |
|
883 |
| - return invoke.execute(frame, inliningTarget, rootCallTarget, args); |
884 |
| - } |
885 |
| - |
886 |
| - @Specialization(guards = {"isMapping(inliningTarget, mappingCheckNode, locals)"}) |
887 |
| - @SuppressWarnings("truffle-static-method") |
888 |
| - Object execInheritGlobalsCustomLocals(VirtualFrame frame, Object source, @SuppressWarnings("unused") PNone globals, Object locals, |
889 |
| - @Bind("this") Node inliningTarget, |
890 |
| - @SuppressWarnings("unused") @Shared @Cached PyMappingCheckNode mappingCheckNode, |
891 |
| - @Exclusive @Cached ReadCallerFrameNode readCallerFrameNode, |
892 |
| - @Shared("getCt") @Cached CodeNodes.GetCodeCallTargetNode getCt, |
893 |
| - @Shared @Cached CallDispatchers.SimpleIndirectInvokeNode invoke, |
894 |
| - @Shared @Cached PRaiseNode raiseNode) { |
895 |
| - PCode code = createAndCheckCode(frame, inliningTarget, source, raiseNode); |
896 |
| - PFrame callerFrame = readCallerFrameNode.executeWith(frame, 0); |
897 |
| - Object[] args = PArguments.create(); |
898 |
| - inheritGlobals(callerFrame, args); |
899 |
| - setCustomLocals(args, locals); |
900 |
| - |
901 |
| - return invoke.execute(frame, inliningTarget, getCt.execute(inliningTarget, code), args); |
| 839 | + return args; |
902 | 840 | }
|
903 | 841 |
|
904 |
| - @Specialization(guards = {"isMapping(inliningTarget, mappingCheckNode, locals)"}) |
905 |
| - @SuppressWarnings("truffle-static-method") |
906 |
| - Object execCustomGlobalsCustomLocals(VirtualFrame frame, Object source, PDict globals, Object locals, |
907 |
| - @Bind("this") Node inliningTarget, |
908 |
| - @SuppressWarnings("unused") @Shared @Cached PyMappingCheckNode mappingCheckNode, |
909 |
| - @Shared @Cached HashingCollectionNodes.SetItemNode setBuiltins, |
910 |
| - @Shared("getCt") @Cached CodeNodes.GetCodeCallTargetNode getCt, |
911 |
| - @Shared @Cached CallDispatchers.SimpleIndirectInvokeNode invoke, |
912 |
| - @Shared @Cached PRaiseNode raiseNode) { |
913 |
| - PCode code = createAndCheckCode(frame, inliningTarget, source, raiseNode); |
914 |
| - Object[] args = PArguments.create(); |
915 |
| - setCustomGlobals(frame, inliningTarget, globals, setBuiltins, args); |
916 |
| - setCustomLocals(args, locals); |
917 |
| - |
918 |
| - return invoke.execute(frame, inliningTarget, getCt.execute(inliningTarget, code), args); |
| 842 | + @Fallback |
| 843 | + static Object[] badGlobals(Node inliningTarget, Object globals, @SuppressWarnings("unused") Object locals, TruffleString mode) { |
| 844 | + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.GLOBALS_MUST_BE_DICT, mode, globals); |
919 | 845 | }
|
920 | 846 |
|
921 |
| - @Specialization(guards = {"!isAnyNone(globals)", "!isDict(globals)"}) |
922 |
| - @SuppressWarnings({"unused", "truffle-static-method"}) |
923 |
| - PNone badGlobals(Object source, Object globals, Object locals, |
924 |
| - @Bind("this") Node inliningTarget) { |
925 |
| - throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.GLOBALS_MUST_BE_DICT, getMode(), globals); |
| 847 | + private static void setCustomLocals(Object[] args, Object locals) { |
| 848 | + PArguments.setSpecialArgument(args, locals); |
926 | 849 | }
|
| 850 | + } |
927 | 851 |
|
928 |
| - @Specialization(guards = {"isAnyNone(globals) || isDict(globals)", "!isAnyNone(locals)", "!isMapping(inliningTarget, mappingCheckNode, locals)"}) |
929 |
| - @SuppressWarnings({"unused", "truffle-static-method"}) |
930 |
| - PNone badLocals(Object source, PDict globals, Object locals, |
931 |
| - @Bind("this") Node inliningTarget, |
932 |
| - @Shared @Cached PyMappingCheckNode mappingCheckNode) { |
933 |
| - throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.LOCALS_MUST_BE_MAPPING, getMode(), locals); |
934 |
| - } |
| 852 | + @GenerateInline |
| 853 | + @GenerateCached(false) |
| 854 | + abstract static class EvalExecNode extends Node { |
| 855 | + abstract Object execute(VirtualFrame frame, Node inliningTarget, Object source, Object globals, Object locals, TruffleString mode, boolean shouldStripLeadingWhitespace); |
935 | 856 |
|
936 |
| - private CompileNode getCompileNode() { |
937 |
| - if (compileNode == null) { |
938 |
| - CompilerDirectives.transferToInterpreterAndInvalidate(); |
939 |
| - compileNode = insert(CompileNode.create(false, shouldStripLeadingWhitespace())); |
| 857 | + @Specialization |
| 858 | + static Object eval(VirtualFrame frame, Node inliningTarget, Object source, Object globals, Object locals, TruffleString mode, @SuppressWarnings("unused") boolean shouldStripLeadingWhitespace, |
| 859 | + @Cached("create(false, shouldStripLeadingWhitespace)") CompileNode compileNode, |
| 860 | + @Cached CreateEvalExecArgumentsNode createArguments, |
| 861 | + @Cached CodeNodes.GetCodeCallTargetNode getCallTarget, |
| 862 | + @Cached CallDispatchers.CallTargetCachedInvokeNode invoke, |
| 863 | + @Cached PRaiseNode raiseNode) { |
| 864 | + PCode code = compileNode.compile(frame, source, T_STRING_SOURCE, mode, -1, -1); |
| 865 | + if (code.getFreeVars().length > 0) { |
| 866 | + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.CODE_OBJ_NO_FREE_VARIABLES, mode); |
940 | 867 | }
|
941 |
| - return compileNode; |
| 868 | + Object[] args = createArguments.execute(frame, inliningTarget, globals, locals, mode); |
| 869 | + RootCallTarget callTarget = getCallTarget.execute(inliningTarget, code); |
| 870 | + return invoke.execute(frame, inliningTarget, callTarget, args); |
942 | 871 | }
|
| 872 | + } |
943 | 873 |
|
944 |
| - private PDict getOrCreateDictNode(PythonObject object) { |
945 |
| - if (getOrCreateDictNode == null) { |
946 |
| - CompilerDirectives.transferToInterpreterAndInvalidate(); |
947 |
| - getOrCreateDictNode = insert(GetOrCreateDictNode.create()); |
948 |
| - } |
949 |
| - return getOrCreateDictNode.executeCached(object); |
950 |
| - } |
| 874 | + // eval(expression, globals=None, locals=None) |
| 875 | + @Builtin(name = J_EVAL, minNumOfPositionalArgs = 1, parameterNames = {"expression", "globals", "locals"}) |
| 876 | + @GenerateNodeFactory |
| 877 | + public abstract static class EvalNode extends PythonBuiltinNode { |
951 | 878 |
|
952 |
| - protected boolean shouldStripLeadingWhitespace() { |
953 |
| - return true; |
| 879 | + @Specialization |
| 880 | + static Object eval(VirtualFrame frame, Object source, Object globals, Object locals, |
| 881 | + @Bind Node inliningTarget, |
| 882 | + @Cached EvalExecNode evalNode) { |
| 883 | + return evalNode.execute(frame, inliningTarget, source, globals, locals, T_EVAL, true); |
954 | 884 | }
|
955 | 885 | }
|
956 | 886 |
|
957 | 887 | @Builtin(name = J_EXEC, minNumOfPositionalArgs = 1, parameterNames = {"source", "globals", "locals"})
|
958 | 888 | @GenerateNodeFactory
|
959 |
| - abstract static class ExecNode extends EvalNode { |
960 |
| - protected abstract Object executeInternal(VirtualFrame frame); |
961 |
| - |
962 |
| - @Override |
963 |
| - protected TruffleString getMode() { |
964 |
| - return T_EXEC; |
965 |
| - } |
966 |
| - |
967 |
| - @Override |
968 |
| - public final Object execute(VirtualFrame frame) { |
969 |
| - executeInternal(frame); |
970 |
| - return PNone.NONE; |
971 |
| - } |
| 889 | + public abstract static class ExecNode extends PythonBuiltinNode { |
972 | 890 |
|
973 |
| - @Override |
974 |
| - protected boolean shouldStripLeadingWhitespace() { |
975 |
| - return false; |
| 891 | + @Specialization |
| 892 | + static Object exec(VirtualFrame frame, Object source, Object globals, Object locals, |
| 893 | + @Bind Node inliningTarget, |
| 894 | + @Cached EvalExecNode evalNode) { |
| 895 | + evalNode.execute(frame, inliningTarget, source, globals, locals, T_EXEC, false); |
| 896 | + return NONE; |
976 | 897 | }
|
977 | 898 | }
|
978 | 899 |
|
|
0 commit comments