diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/MarshalModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/MarshalModuleBuiltins.java index f633b86e2b..307bcd7ddc 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/MarshalModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/MarshalModuleBuiltins.java @@ -1292,8 +1292,13 @@ private void setSource(Source s) { } private Source getSource() { - assert source != null; - return source; + if (source != null) { + return source; + } else { + // This should never happen when deserializing a bytecode DSL code unit, but could + // happen if the user tries to deserialize arbitrary bytes. + throw new MarshalError(ValueError, ErrorMessages.BAD_MARSHAL_DATA); + } } private void writeSparseTable(int[][] table) { @@ -1330,8 +1335,9 @@ private CodeUnit readCodeUnit() { private BytecodeCodeUnit readBytecodeCodeUnit() { if (PythonOptions.ENABLE_BYTECODE_DSL_INTERPRETER) { - throw new AssertionError( - "Attempted to deserialize a code object from the manual bytecode interpreter, but the DSL interpreter is enabled. Consider clearing or setting a different pycache folder."); + throw new MarshalError(ValueError, + PythonUtils.tsLiteral( + "Attempted to deserialize a code object from the manual bytecode interpreter, but the DSL interpreter is enabled. Consider clearing or setting a different pycache folder.")); } int fileVersion = readByte(); @@ -1375,8 +1381,9 @@ private BytecodeCodeUnit readBytecodeCodeUnit() { private BytecodeDSLCodeUnit readBytecodeDSLCodeUnit() { if (!PythonOptions.ENABLE_BYTECODE_DSL_INTERPRETER) { - throw new AssertionError( - "Attempted to deserialize a code object from the Bytecode DSL interpreter, but the manual interpreter is enabled. Consider clearing or setting a different pycache folder."); + throw new MarshalError(ValueError, + PythonUtils.tsLiteral( + "Attempted to deserialize a code object from the Bytecode DSL interpreter, but the manual interpreter is enabled. Consider clearing or setting a different pycache folder.")); } byte[] serialized = readBytes(); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/compiler/bytecode_dsl/RootNodeCompiler.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/compiler/bytecode_dsl/RootNodeCompiler.java index cb2e470c48..1fb3be8dcd 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/compiler/bytecode_dsl/RootNodeCompiler.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/compiler/bytecode_dsl/RootNodeCompiler.java @@ -1411,7 +1411,7 @@ private void emitCall(ExprTy func, ExprTy[] args, KeywordTy[] keywords) { b.emitLoadLocal(function); b.endBlock(); - emitUnstar(args, receiver); + emitUnstar(() -> b.emitLoadLocal(receiver), args); emitKeywords(keywords, function); } else { assert len(keywords) == 0; @@ -1665,9 +1665,11 @@ private void createConstant(ConstantValue value) { break; case TUPLE: b.beginMakeTuple(); - for (ConstantValue cv : value.getFrozensetElements()) { + b.beginMakeVariadic(); + for (ConstantValue cv : value.getTupleElements()) { createConstant(cv); } + b.endMakeVariadic(); b.endMakeTuple(); break; case FROZENSET: @@ -1944,18 +1946,19 @@ private void emitConstantTuple(ConstantCollection constantCollection) { * @param args the sequence of expressions */ private void emitUnstar(ExprTy[] args) { - emitUnstar(args, null); + emitUnstar(null, args); } /** - * Same as above, but takes an optional receiver local. This is only used for method calls - * where the receiver needs to be included in the positional arguments. + * Same as above, but takes an optional Runnable to produce elements at the beginning of the + * sequence. * + * @param initialElementsProducer a runnable to produce the first element(s) of the + * sequence. * @param args the sequence of expressions to unstar - * @param receiver an optional local storing the receiver */ - private void emitUnstar(ExprTy[] args, BytecodeLocal receiver) { - if (len(args) == 0 && receiver == null) { + private void emitUnstar(Runnable initialElementsProducer, ExprTy[] args) { + if (len(args) == 0 && initialElementsProducer == null) { b.emitLoadConstant(PythonUtils.EMPTY_OBJECT_ARRAY); } else if (anyIsStarred(args)) { /** @@ -1979,10 +1982,10 @@ private void emitUnstar(ExprTy[] args, BytecodeLocal receiver) { boolean inVariadic = false; int numOperands = 0; - if (receiver != null) { + if (initialElementsProducer != null) { b.beginMakeVariadic(); + initialElementsProducer.run(); inVariadic = true; - b.emitLoadLocal(receiver); } for (int i = 0; i < args.length; i++) { @@ -2015,8 +2018,8 @@ private void emitUnstar(ExprTy[] args, BytecodeLocal receiver) { b.endUnstar(numOperands); } else { b.beginMakeVariadic(); - if (receiver != null) { - b.emitLoadLocal(receiver); + if (initialElementsProducer != null) { + initialElementsProducer.run(); } visitSequence(args); b.endMakeVariadic(); @@ -2925,13 +2928,13 @@ public Void visit(StmtTy.ClassDef node) { b.emitLoadLocal(buildClassFunction); // positional args - b.beginMakeVariadic(); - emitMakeFunction(node, node.name, null, null); - emitPythonConstant(toTruffleStringUncached(node.name), b); - visitSequence(node.bases); - b.endMakeVariadic(); + emitUnstar(() -> { + emitMakeFunction(node, node.name, null, null); + emitPythonConstant(toTruffleStringUncached(node.name), b); + }, node.bases); // keyword args + validateKeywords(node.keywords); emitKeywords(node.keywords, buildClassFunction); b.endCallVarargsMethod(); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode_dsl/PBytecodeDSLRootNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode_dsl/PBytecodeDSLRootNode.java index ca1d2efc64..b0fe68639e 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode_dsl/PBytecodeDSLRootNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode_dsl/PBytecodeDSLRootNode.java @@ -271,7 +271,7 @@ @ShortCircuitOperation(name = "PrimitiveBoolOr", booleanConverter = PBytecodeDSLRootNode.BooleanIdentity.class, operator = Operator.OR_RETURN_CONVERTED) @SuppressWarnings("unused") public abstract class PBytecodeDSLRootNode extends PRootNode implements BytecodeRootNode { - private static final int EXPLODE_LOOP_THRESHOLD = 32; + public static final int EXPLODE_LOOP_THRESHOLD = 32; private static final BytecodeConfig TRACE_AND_PROFILE_CONFIG = PBytecodeDSLRootNodeGen.newConfigBuilder() // .addInstrumentation(TraceOrProfileCall.class) // .addInstrumentation(TraceLine.class) // @@ -379,7 +379,7 @@ public static void doExit(VirtualFrame frame, AbstractTruffleException ate, @Bind("$root") PBytecodeDSLRootNode root, @Bind("this") Node location) { if (ate instanceof PException pe) { - pe.notifyAddedTracebackFrame(!root.isPythonInternal()); + pe.notifyAddedTracebackFrame(!root.isInternal()); } if (root.needsTraceAndProfileInstrumentation()) { @@ -1904,37 +1904,34 @@ public static PList perform(Object[] elements, } @Operation + @ImportStatic({PBytecodeDSLRootNode.class}) public static final class MakeSet { - @Specialization - public static PSet perform(VirtualFrame frame, Object[] elements, + @Specialization(guards = {"elements.length == length", "length <= EXPLODE_LOOP_THRESHOLD"}, limit = "1") + @ExplodeLoop + public static PSet performExploded(VirtualFrame frame, Object[] elements, @Bind("$root") PBytecodeDSLRootNode rootNode, @Bind("this") Node node, - @Cached(value = "elements.length", neverDefault = false) int length, - @Cached SetNodes.AddNode addNode, - @Cached HashingCollectionNodes.SetItemNode setItemNode) { - assert elements.length == length; - + @Cached(value = "elements.length") int length, + @Shared @Cached SetNodes.AddNode addNode, + @Shared @Cached HashingCollectionNodes.SetItemNode setItemNode) { PSet set = rootNode.factory.createSet(); - if (length <= EXPLODE_LOOP_THRESHOLD) { - doExploded(frame, set, elements, length, addNode, setItemNode); - } else { - doRegular(frame, set, elements, length, addNode, setItemNode); - } - return set; - } - - @ExplodeLoop - private static void doExploded(VirtualFrame frame, PSet set, Object[] elements, int length, SetNodes.AddNode addNode, HashingCollectionNodes.SetItemNode setItemNode) { - CompilerAsserts.partialEvaluationConstant(length); for (int i = 0; i < length; i++) { SetNodes.AddNode.add(frame, set, elements[i], addNode, setItemNode); } + return set; } - private static void doRegular(VirtualFrame frame, PSet set, Object[] elements, int length, SetNodes.AddNode addNode, HashingCollectionNodes.SetItemNode setItemNode) { - for (int i = 0; i < length; i++) { + @Specialization + public static PSet performRegular(VirtualFrame frame, Object[] elements, + @Bind("$root") PBytecodeDSLRootNode rootNode, + @Bind("this") Node node, + @Shared @Cached SetNodes.AddNode addNode, + @Shared @Cached HashingCollectionNodes.SetItemNode setItemNode) { + PSet set = rootNode.factory.createSet(); + for (int i = 0; i < elements.length; i++) { SetNodes.AddNode.add(frame, set, elements[i], addNode, setItemNode); } + return set; } } @@ -1999,54 +1996,9 @@ public static PList perform(@Bind("$root") PBytecodeDSLRootNode rootNode) { @Operation public static final class MakeTuple { @Specialization - public static Object perform(@Variadic Object[] elements, - @Cached(value = "elements.length", neverDefault = false) int length, + public static Object perform(Object[] elements, @Bind("$root") PBytecodeDSLRootNode rootNode) { - assert elements.length == length; - - Object[] elts; - if (length <= EXPLODE_LOOP_THRESHOLD) { - elts = doExploded(elements, length); - } else { - elts = doRegular(elements, length); - } - return rootNode.factory.createTuple(elts); - } - - @ExplodeLoop - private static Object[] doExploded(Object[] elements, int length) { - CompilerAsserts.partialEvaluationConstant(length); - int totalLength = 0; - for (int i = 0; i < length; i++) { - totalLength += ((Object[]) elements[i]).length; - } - - Object[] elts = new Object[totalLength]; - int idx = 0; - for (int i = 0; i < length; i++) { - Object[] arr = (Object[]) elements[i]; - int len = arr.length; - System.arraycopy(arr, 0, elts, idx, len); - idx += len; - } - return elts; - } - - private static Object[] doRegular(Object[] elements, int length) { - int totalLength = 0; - for (int i = 0; i < length; i++) { - totalLength += ((Object[]) elements[i]).length; - } - - Object[] elts = new Object[totalLength]; - int idx = 0; - for (int i = 0; i < length; i++) { - Object[] arr = (Object[]) elements[i]; - int len = arr.length; - System.arraycopy(arr, 0, elts, idx, len); - idx += len; - } - return elts; + return rootNode.factory.createTuple(elements); } } @@ -3621,7 +3573,7 @@ public static void doExceptional(VirtualFrame frame, Object result = callExit.execute(frame, exit, contextManager, excType, pythonException, excTraceback); if (!isTrue.execute(frame, inliningTarget, result)) { if (exception instanceof PException pException) { - throw pException.getExceptionForReraise(rootNode.isPythonInternal()); + throw pException.getExceptionForReraise(!rootNode.isInternal()); } else if (exception instanceof AbstractTruffleException ate) { throw ate; } else { @@ -3723,7 +3675,7 @@ public static void doExceptional(VirtualFrame frame, @Cached PRaiseNode.Lazy raiseNode) { if (!isTrue.execute(frame, inliningTarget, result)) { if (exception instanceof PException) { - throw ((PException) exception).getExceptionForReraise(rootNode.isPythonInternal()); + throw ((PException) exception).getExceptionForReraise(!rootNode.isInternal()); } else if (exception instanceof AbstractTruffleException) { throw (AbstractTruffleException) exception; } else {