diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/datetime/DateBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/datetime/DateBuiltins.java index a37100e563..422c5aa012 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/datetime/DateBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/datetime/DateBuiltins.java @@ -95,10 +95,10 @@ import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.builtins.objects.type.TypeNodes; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryOp.BinaryOpBuiltinNode; -import com.oracle.graal.python.lib.PyFloatAsDoubleNode; -import com.oracle.graal.python.lib.PyFloatCheckNode; import com.oracle.graal.python.lib.PyDateCheckNode; import com.oracle.graal.python.lib.PyDeltaCheckNode; +import com.oracle.graal.python.lib.PyFloatAsDoubleNode; +import com.oracle.graal.python.lib.PyFloatCheckNode; import com.oracle.graal.python.lib.PyLongAsLongNode; import com.oracle.graal.python.lib.PyObjectCallMethodObjArgs; import com.oracle.graal.python.lib.PyObjectHashNode; @@ -120,7 +120,9 @@ import com.oracle.graal.python.nodes.util.CastToJavaStringNode; import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; import com.oracle.graal.python.runtime.ExecutionContext; +import com.oracle.graal.python.runtime.ExecutionContext.BoundaryCallContext; import com.oracle.graal.python.runtime.IndirectCallData; +import com.oracle.graal.python.runtime.IndirectCallData.BoundaryCallData; import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Bind; @@ -129,7 +131,6 @@ import com.oracle.truffle.api.dsl.NodeFactory; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.nodes.EncapsulatingNodeReference; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.strings.TruffleString; @@ -176,7 +177,7 @@ public void postInitialize(Python3Core core) { public abstract static class NewNode extends PythonBuiltinNode { @Specialization - static Object newDate(Object cls, Object yearObject, Object monthObject, Object dayObject, + static Object newDate(VirtualFrame frame, Object cls, Object yearObject, Object monthObject, Object dayObject, @Bind Node inliningTarget, @Cached PRaiseNode raiseNode, @Cached BytesNodes.ToBytesNode toBytesNode, @@ -215,7 +216,7 @@ static Object newDate(Object cls, Object yearObject, Object monthObject, Object } } - return newNode.execute(inliningTarget, cls, yearObject, monthObject, dayObject); + return newNode.execute(frame, inliningTarget, cls, yearObject, monthObject, dayObject); } /** @@ -377,7 +378,7 @@ private static Object addBoundary(Object left, Object right, Node inliningTarget } LocalDate localDate = ChronoUnit.DAYS.addTo(from, days - 1); - return DateNodes.SubclassNewNode.getUncached().execute(inliningTarget, + return DateNodes.SubclassNewNode.executeUncached( getResultDateType(dateObj), localDate.getYear(), localDate.getMonthValue(), @@ -442,7 +443,7 @@ private static Object subBoundary(Object left, Object right, Node inliningTarget } LocalDate localDate = ChronoUnit.DAYS.addTo(from, days - 1); - return DateNodes.SubclassNewNode.getUncached().execute(inliningTarget, + return DateNodes.SubclassNewNode.executeUncached( getResultDateType(left), localDate.getYear(), localDate.getMonthValue(), @@ -543,7 +544,7 @@ static Object today(VirtualFrame frame, Object cls, @TruffleBoundary private static Object todayBoundary(Object cls, Node inliningTarget) { var localDate = LocalDate.now(); - return DateNodes.SubclassNewNode.getUncached().execute(inliningTarget, cls, localDate.getYear(), localDate.getMonthValue(), localDate.getDayOfMonth()); + return DateNodes.SubclassNewNode.executeUncached(cls, localDate.getYear(), localDate.getMonthValue(), localDate.getDayOfMonth()); } } @@ -552,17 +553,14 @@ private static Object todayBoundary(Object cls, Node inliningTarget) { public abstract static class FromTimestampNode extends PythonBinaryBuiltinNode { @Specialization - static Object fromTimestamp(Object cls, Object timestampObject, - @Bind Node inliningTarget) { - EncapsulatingNodeReference encapsulating = EncapsulatingNodeReference.getCurrent(); - Node encapsulatingNode = encapsulating.set(inliningTarget); + static Object fromTimestamp(VirtualFrame frame, Object cls, Object timestampObject, + @Bind Node inliningTarget, + @Cached("createFor($node)") BoundaryCallData callData) { + Object saved = BoundaryCallContext.enter(frame, callData); try { return fromTimestampBoundary(cls, timestampObject, inliningTarget); } finally { - // Some uncached nodes (e.g. PyFloatAsDoubleNode and PyLongAsLongNode) - // may raise exceptions that are not connected to a current node. Set - // the current node manually. - encapsulating.set(encapsulatingNode); + BoundaryCallContext.exit(frame, callData, saved); } } @@ -586,7 +584,7 @@ private static Object fromTimestampBoundary(Object cls, Object timestampObject, TimeZone timeZone = TimeModuleBuiltins.getGlobalTimeZone(getContext(inliningTarget)); ZoneId zoneId = timeZone.toZoneId(); LocalDate localDate = LocalDate.ofInstant(instant, zoneId); - return DateNodes.SubclassNewNode.getUncached().execute(inliningTarget, cls, localDate.getYear(), localDate.getMonthValue(), localDate.getDayOfMonth()); + return DateNodes.SubclassNewNode.executeUncached(cls, localDate.getYear(), localDate.getMonthValue(), localDate.getDayOfMonth()); } } @@ -620,7 +618,7 @@ static Object fromIsoCalendar(VirtualFrame frame, Object cls, long year, long we private static Object fromIsoCalendarBoundary(Object cls, long year, long week, long dayOfWeek, Node inliningTarget) { DatetimeModuleBuiltins.validateIsoCalendarComponentsAndRaise(inliningTarget, year, week, dayOfWeek); LocalDate localDate = LocalDate.now().with(IsoFields.WEEK_BASED_YEAR, year).with(IsoFields.WEEK_OF_WEEK_BASED_YEAR, week).with(ChronoField.DAY_OF_WEEK, dayOfWeek); - return DateNodes.SubclassNewNode.getUncached().execute(inliningTarget, cls, localDate.getYear(), localDate.getMonthValue(), localDate.getDayOfMonth()); + return DateNodes.SubclassNewNode.executeUncached(cls, localDate.getYear(), localDate.getMonthValue(), localDate.getDayOfMonth()); } } @@ -715,7 +713,7 @@ private static Object parseIsoDateFormat(String source, Node inliningTarget, Obj } LocalDate localDate = LocalDate.now().with(IsoFields.WEEK_BASED_YEAR, year).with(IsoFields.WEEK_OF_WEEK_BASED_YEAR, week).with(ChronoField.DAY_OF_WEEK, dayOfWeek); - return DateNodes.SubclassNewNode.getUncached().execute(inliningTarget, + return DateNodes.SubclassNewNode.executeUncached( cls, localDate.getYear(), localDate.getMonthValue(), @@ -737,7 +735,7 @@ private static Object parseIsoDateFormat(String source, Node inliningTarget, Obj return null; } - return DateNodes.SubclassNewNode.getUncached().execute(inliningTarget, cls, year, month, day); + return DateNodes.SubclassNewNode.executeUncached(cls, year, month, day); } catch (IndexOutOfBoundsException e) { return null; } @@ -791,7 +789,7 @@ static Object replace(VirtualFrame frame, Object self, Object yearObject, Object day = (int) longAsLongNode.execute(frame, inliningTarget, dayObject); } - return newNode.execute(inliningTarget, getClassNode.execute(inliningTarget, self), year, month, day); + return newNode.execute(frame, inliningTarget, getClassNode.execute(inliningTarget, self), year, month, day); } } @@ -843,7 +841,7 @@ private static Object fromOrdinalBoundary(Object cls, long days, Node inliningTa LocalDate baseLocalDate = LocalDate.of(1, 1, 1); LocalDate localDate = ChronoUnit.DAYS.addTo(baseLocalDate, days - 1); - return DateNodes.SubclassNewNode.getUncached().execute(inliningTarget, cls, localDate.getYear(), localDate.getMonthValue(), localDate.getDayOfMonth()); + return DateNodes.SubclassNewNode.executeUncached(cls, localDate.getYear(), localDate.getMonthValue(), localDate.getDayOfMonth()); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/datetime/DateNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/datetime/DateNodes.java index ad8fb02f47..403775d447 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/datetime/DateNodes.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/datetime/DateNodes.java @@ -49,6 +49,7 @@ import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.PythonBuiltinClassType; +import com.oracle.graal.python.builtins.modules.datetime.DateNodesFactory.NewNodeGen; import com.oracle.graal.python.builtins.objects.cext.PythonAbstractNativeObject; import com.oracle.graal.python.builtins.objects.cext.capi.CApiContext; import com.oracle.graal.python.builtins.objects.cext.capi.ExternalFunctionInvoker; @@ -64,17 +65,17 @@ import com.oracle.graal.python.nodes.PGuards; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.call.CallNode; +import com.oracle.graal.python.runtime.ExecutionContext.BoundaryCallContext; import com.oracle.graal.python.runtime.IndirectCallData.BoundaryCallData; import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.nativeaccess.NativeMemory; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.GenerateCached; import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.GenerateUncached; import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.nodes.EncapsulatingNodeReference; +import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.object.Shape; @@ -85,19 +86,28 @@ public class DateNodes { @GenerateCached(false) public abstract static class NewNode extends Node { - public abstract Object execute(Node inliningTarget, Object cls, Object yearObject, Object monthObject, Object dayObject); + public abstract Object execute(VirtualFrame frame, Node inliningTarget, Object cls, Object yearObject, Object monthObject, Object dayObject); + + /** + * Executes without access to the current Python frame. This overload may only be used when {@code cls} is + * {@link PythonBuiltinClassType} and all remaining arguments are known to be valid builtin values. + */ + public final Object execute(Node inliningTarget, Object cls, Object yearObject, Object monthObject, Object dayObject) { + return execute(null, inliningTarget, cls, yearObject, monthObject, dayObject); + } + + public static Object executeUncached(Object cls, Object yearObject, Object monthObject, Object dayObject) { + return NewNodeGen.getUncached().execute(NewNodeGen.getUncached(), cls, yearObject, monthObject, dayObject); + } @Specialization - static Object newDate(Node inliningTarget, Object cls, Object yearObject, Object monthObject, Object dayObject) { - EncapsulatingNodeReference encapsulating = EncapsulatingNodeReference.getCurrent(); - Node encapsulatingNode = encapsulating.set(inliningTarget); + static Object newDate(VirtualFrame frame, Node inliningTarget, Object cls, Object yearObject, Object monthObject, Object dayObject, + @Cached("createFor($node)") BoundaryCallData callData) { + Object saved = BoundaryCallContext.enter(frame, callData); try { return newDateBoundary(inliningTarget, cls, yearObject, monthObject, dayObject); } finally { - // Some uncached nodes (e.g. PyLongAsLongNode) may raise exceptions - // that are not connected to a current node. Set the current node - // manually. - encapsulating.set(encapsulatingNode); + BoundaryCallContext.exit(frame, callData, saved); } } @@ -167,31 +177,13 @@ static Object newDate(Node inliningTarget, Object cls, int year, int month, int } } - @GenerateUncached - @GenerateInline - @GenerateCached(false) - public abstract static class SubclassNewNode extends Node { - - public abstract Object execute(Node inliningTarget, Object cls, Object yearObject, Object monthObject, Object dayObject); - - public static SubclassNewNode getUncached() { - return DateNodesFactory.SubclassNewNodeGen.getUncached(); - } - - @Specialization(guards = {"isBuiltinClass(cls)"}) - static Object newDateBuiltin(Node inliningTarget, Object cls, Object yearObject, Object monthObject, Object dayObject, - @Cached NewNode newNode) { - return newNode.execute(inliningTarget, cls, yearObject, monthObject, dayObject); - } - - @Fallback - @TruffleBoundary - static Object newDateGeneric(Object cls, Object yearObject, Object monthObject, Object dayObject) { - return CallNode.executeUncached(cls, yearObject, monthObject, dayObject); - } - - static boolean isBuiltinClass(Object cls) { - return PGuards.isBuiltinClass(cls, PythonBuiltinClassType.PDate); + public abstract static class SubclassNewNode { + public static Object executeUncached(Object cls, Object yearObject, Object monthObject, Object dayObject) { + if (PGuards.isBuiltinClass(cls, PythonBuiltinClassType.PDate)) { + return NewNode.executeUncached(cls, yearObject, monthObject, dayObject); + } else { + return CallNode.executeUncached(cls, yearObject, monthObject, dayObject); + } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/datetime/DateTimeBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/datetime/DateTimeBuiltins.java index c617260541..fbb64b66e8 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/datetime/DateTimeBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/datetime/DateTimeBuiltins.java @@ -148,7 +148,6 @@ import com.oracle.truffle.api.dsl.NodeFactory; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.nodes.EncapsulatingNodeReference; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.object.Shape; import com.oracle.truffle.api.strings.TruffleString; @@ -403,18 +402,15 @@ static Object str(VirtualFrame frame, Object self, public abstract static class ReprNode extends PythonUnaryBuiltinNode { @Specialization - static TruffleString repr(Object selfObj, + static TruffleString repr(VirtualFrame frame, Object selfObj, @Bind Node inliningTarget, - @Cached DateTimeNodes.TzInfoNode tzInfoNode) { - EncapsulatingNodeReference encapsulating = EncapsulatingNodeReference.getCurrent(); - Node encapsulatingNode = encapsulating.set(inliningTarget); + @Cached DateTimeNodes.TzInfoNode tzInfoNode, + @Cached("createFor($node)") IndirectCallData.BoundaryCallData boundaryCallData) { + Object saved = ExecutionContext.BoundaryCallContext.enter(frame, boundaryCallData); try { return reprBoundary(inliningTarget, selfObj, tzInfoNode.execute(inliningTarget, selfObj)); } finally { - // Some uncached nodes (e.g. PyFloatAsDoubleNode, PyLongAsLongNode, - // PyObjectReprAsObjectNode) may raise exceptions that are not - // connected to a current node. Set the current node manually. - encapsulating.set(encapsulatingNode); + ExecutionContext.BoundaryCallContext.exit(frame, boundaryCallData, saved); } } @@ -1818,11 +1814,11 @@ static Object strptime(VirtualFrame frame, Object cls, TruffleString stringTs, T abstract static class DateNode extends PythonUnaryBuiltinNode { @Specialization - static Object getDate(Object selfObj, + static Object getDate(VirtualFrame frame, Object selfObj, @Bind Node inliningTarget, @Cached DateNodes.NewNode newDateNode) { DateTimeValue self = TemporalValueNodes.GetDateTimeValue.executeUncached(inliningTarget, selfObj); - return newDateNode.execute(inliningTarget, + return newDateNode.execute(frame, inliningTarget, PythonBuiltinClassType.PDate, self.year, self.month, @@ -1835,11 +1831,11 @@ static Object getDate(Object selfObj, abstract static class TimeNode extends PythonUnaryBuiltinNode { @Specialization - static Object getTime(Object selfObj, + static Object getTime(VirtualFrame frame, Object selfObj, @Bind Node inliningTarget, @Cached TimeNodes.NewNode newTimeNode) { DateTimeValue self = TemporalValueNodes.GetDateTimeValue.executeUncached(inliningTarget, selfObj); - return newTimeNode.execute(inliningTarget, + return newTimeNode.execute(frame, inliningTarget, PythonBuiltinClassType.PTime, self.hour, self.minute, @@ -1855,12 +1851,12 @@ static Object getTime(Object selfObj, abstract static class TimeTzNode extends PythonUnaryBuiltinNode { @Specialization - static Object getTime(Object selfObj, + static Object getTime(VirtualFrame frame, Object selfObj, @Bind Node inliningTarget, @Cached DateTimeNodes.TzInfoNode tzInfoNode, @Cached TimeNodes.NewNode newTimeNode) { DateTimeValue self = TemporalValueNodes.GetDateTimeValue.executeUncached(inliningTarget, selfObj); - return newTimeNode.execute(inliningTarget, + return newTimeNode.execute(frame, inliningTarget, PythonBuiltinClassType.PTime, self.hour, self.minute, @@ -2045,8 +2041,7 @@ private static PTimeZone getSystemTimeZoneAt(LocalDateTime localDateTime, int fo long timestampMillis = timestamp * 1_000; int offsetMilliseconds = timeZone.getOffset(timestampMillis); - Object timeDeltaType = PythonBuiltinClassType.PTimeDelta; - Object offset = TimeDeltaNodes.NewNode.getUncached().execute(inliningTarget, timeDeltaType, 0, 0, 0, offsetMilliseconds, 0, 0, 0); + Object offset = TimeDeltaNodes.NewNode.getUncached().execute(inliningTarget, PythonBuiltinClassType.PTimeDelta, 0, 0, 0, offsetMilliseconds, 0, 0, 0); Object timeZoneType = PythonBuiltinClassType.PTimezone; TruffleString timeZoneNameTS = TruffleString.FromJavaStringNode.getUncached().execute(timeZoneName, TS_ENCODING); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/datetime/TimeBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/datetime/TimeBuiltins.java index fcc8bf2859..0cedaa337d 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/datetime/TimeBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/datetime/TimeBuiltins.java @@ -163,7 +163,7 @@ public void postInitialize(Python3Core core) { public abstract static class NewNode extends PythonBuiltinNode { @Specialization - static Object newTime(Object cls, Object hourObject, Object minuteObject, Object secondObject, Object microsecondObject, Object tzInfoObject, Object foldObject, + static Object newTime(VirtualFrame frame, Object cls, Object hourObject, Object minuteObject, Object secondObject, Object microsecondObject, Object tzInfoObject, Object foldObject, @Bind Node inliningTarget, @Cached BytesNodes.ToBytesNode toBytesNode, @Cached TimeNodes.NewNode newTimeNode) { @@ -177,7 +177,7 @@ static Object newTime(Object cls, Object hourObject, Object minuteObject, Object } // ordinal constructor call - return newTimeNode.execute(inliningTarget, cls, hourObject, minuteObject, secondObject, microsecondObject, tzInfoObject, foldObject); + return newTimeNode.execute(frame, inliningTarget, cls, hourObject, minuteObject, secondObject, microsecondObject, tzInfoObject, foldObject); } @TruffleBoundary @@ -1039,7 +1039,7 @@ static Object replace(VirtualFrame frame, Object self, Object hourObject, Object } Object type = getResultTimeType(self, inliningTarget, isForeignObjectNode, getClassNode); - return newTimeNode.execute(inliningTarget, type, hour, minute, second, microsecond, tzInfo, fold); + return newTimeNode.execute(frame, inliningTarget, type, hour, minute, second, microsecond, tzInfo, fold); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/datetime/TimeDeltaBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/datetime/TimeDeltaBuiltins.java index 6a2a2bc432..f3296914da 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/datetime/TimeDeltaBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/datetime/TimeDeltaBuiltins.java @@ -97,6 +97,8 @@ import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; import com.oracle.graal.python.nodes.object.GetClassNode; import com.oracle.graal.python.nodes.util.CastToJavaBigIntegerNode; +import com.oracle.graal.python.runtime.ExecutionContext.BoundaryCallContext; +import com.oracle.graal.python.runtime.IndirectCallData.BoundaryCallData; import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Bind; @@ -150,10 +152,10 @@ public void postInitialize(Python3Core core) { public abstract static class NewNode extends PythonBuiltinNode { @Specialization - static Object newTimeDelta(Object cls, Object days, Object seconds, Object microseconds, Object milliseconds, Object minutes, Object hours, Object weeks, + static Object newTimeDelta(VirtualFrame frame, Object cls, Object days, Object seconds, Object microseconds, Object milliseconds, Object minutes, Object hours, Object weeks, @Bind Node inliningTarget, @Cached TimeDeltaNodes.NewNode newNode) { - return newNode.execute(inliningTarget, cls, days, seconds, microseconds, milliseconds, minutes, hours, weeks); + return newNode.execute(frame, inliningTarget, cls, days, seconds, microseconds, milliseconds, minutes, hours, weeks); } } @@ -321,7 +323,7 @@ static long hash(VirtualFrame frame, Object selfObj, abstract static class AddNode extends BinaryOpBuiltinNode { @Specialization - static Object add(Object left, Object right, + static Object add(VirtualFrame frame, Object left, Object right, @Bind Node inliningTarget, @Cached TimeDeltaNodes.NewNode newNode, @Cached PyDeltaCheckNode checkNode, @@ -331,7 +333,7 @@ static Object add(Object left, Object right, } TimeDeltaValue self = readTimeDeltaValueNode.execute(inliningTarget, left); TimeDeltaValue other = readTimeDeltaValueNode.execute(inliningTarget, right); - return newNode.executeBuiltin(inliningTarget, self.days + other.days, self.seconds + other.seconds, self.microseconds + other.microseconds, 0, 0, 0, 0); + return newNode.executeBuiltin(frame, inliningTarget, self.days + other.days, self.seconds + other.seconds, self.microseconds + other.microseconds, 0, 0, 0, 0); } } @@ -341,7 +343,7 @@ static Object add(Object left, Object right, abstract static class SubNode extends BinaryOpBuiltinNode { @Specialization - static Object sub(Object left, Object rigth, + static Object sub(VirtualFrame frame, Object left, Object rigth, @Bind Node inliningTarget, @Cached TimeDeltaNodes.NewNode newNode, @Cached PyDeltaCheckNode checkNode, @@ -351,53 +353,47 @@ static Object sub(Object left, Object rigth, } TimeDeltaValue self = readTimeDeltaValueNode.execute(inliningTarget, left); TimeDeltaValue other = readTimeDeltaValueNode.execute(inliningTarget, rigth); - return newNode.executeBuiltin(inliningTarget, self.days - other.days, self.seconds - other.seconds, self.microseconds - other.microseconds, 0, 0, 0, 0); + return newNode.executeBuiltin(frame, inliningTarget, self.days - other.days, self.seconds - other.seconds, self.microseconds - other.microseconds, 0, 0, 0, 0); } } @TruffleBoundary private static PInt divideNearest(Node node, Object a, Object b) { - EncapsulatingNodeReference encapsulating = EncapsulatingNodeReference.getCurrent(); - Node encapsulatingNode = encapsulating.set(node); - try { - BigInteger dividend = CastToJavaBigIntegerNode.executeUncached(a); - BigInteger divisor = CastToJavaBigIntegerNode.executeUncached(b); - if (divisor.equals(BigInteger.ZERO)) { - throw PRaiseNode.raiseStatic(node, ZeroDivisionError, ErrorMessages.INTEGER_DIVISION_OR_MODULO_BY_ZERO); - } - BigInteger[] qr = dividend.divideAndRemainder(divisor); - BigInteger quotient = qr[0]; - BigInteger remainder = qr[1]; - - // Scale to compare (remainder * 2) - BigInteger doubleRemainder = remainder.abs().multiply(BigInteger.valueOf(2)); - int cmp = doubleRemainder.compareTo(divisor.abs()); - - BigInteger result; - - if (cmp < 0) { - // Remainder < 0.5, round down (do nothing) - result = quotient; + BigInteger dividend = CastToJavaBigIntegerNode.executeUncached(a); + BigInteger divisor = CastToJavaBigIntegerNode.executeUncached(b); + if (divisor.equals(BigInteger.ZERO)) { + throw PRaiseNode.raiseStatic(node, ZeroDivisionError, ErrorMessages.INTEGER_DIVISION_OR_MODULO_BY_ZERO); + } + BigInteger[] qr = dividend.divideAndRemainder(divisor); + BigInteger quotient = qr[0]; + BigInteger remainder = qr[1]; + + // Scale to compare (remainder * 2) + BigInteger doubleRemainder = remainder.abs().multiply(BigInteger.valueOf(2)); + int cmp = doubleRemainder.compareTo(divisor.abs()); + + BigInteger result; + + if (cmp < 0) { + // Remainder < 0.5, round down (do nothing) + result = quotient; + } else { + BigInteger addend = dividend.signum() == divisor.signum() ? BigInteger.ONE : BigInteger.ONE.negate(); + if (cmp > 0) { + // Remainder > 0.5, round up + result = quotient.add(addend); } else { - BigInteger addend = dividend.signum() == divisor.signum() ? BigInteger.ONE : BigInteger.ONE.negate(); - if (cmp > 0) { - // Remainder > 0.5, round up - result = quotient.add(addend); + // Exactly halfway + // If quotient is even, return quotient + // If odd, round to nearest even (add or subtract 1) + if (quotient.mod(BigInteger.valueOf(2)).equals(BigInteger.ZERO)) { + result = quotient; } else { - // Exactly halfway - // If quotient is even, return quotient - // If odd, round to nearest even (add or subtract 1) - if (quotient.mod(BigInteger.valueOf(2)).equals(BigInteger.ZERO)) { - result = quotient; - } else { - result = quotient.add(addend); - } + result = quotient.add(addend); } } - return PFactory.createInt(PythonLanguage.get(null), result); - } finally { - encapsulating.set(encapsulatingNode); } + return PFactory.createInt(PythonLanguage.get(null), result); } @Slot(value = SlotKind.nb_multiply, isComplex = true) @@ -417,7 +413,8 @@ static Object mul(VirtualFrame frame, Object left, Object right, @Cached PyNumberMultiplyNode multiplyNode, @Cached TimeDeltaNodes.NewNode newNode, @Cached PyDeltaCheckNode checkNode, - @Cached TemporalValueNodes.GetTimeDeltaValue readTimeDeltaValueNode) { + @Cached TemporalValueNodes.GetTimeDeltaValue readTimeDeltaValueNode, + @Cached("createFor($node)") BoundaryCallData boundaryCallData) { TimeDeltaValue date; Object other; if (checkNode.execute(inliningTarget, left)) { @@ -431,7 +428,7 @@ static Object mul(VirtualFrame frame, Object left, Object right, Object selfAsMicroseconds = toMicroseconds(date, addNode, multiplyNode); Object microseconds = multiplyNode.execute(null, selfAsMicroseconds, other); - return newNode.executeBuiltin(inliningTarget, 0, 0, microseconds, 0, 0, 0, 0); + return newNode.executeBuiltin(frame, inliningTarget, 0, 0, microseconds, 0, 0, 0, 0); } else if (floatCheckNode.execute(inliningTarget, other)) { Object selfAsMicroseconds = toMicroseconds(date, addNode, multiplyNode); @@ -442,9 +439,15 @@ static Object mul(VirtualFrame frame, Object left, Object right, Object denominator = tupleGetItem.execute(inliningTarget, ratioTuple, 1); Object multiplyResult = multiplyNode.execute(frame, selfAsMicroseconds, numerator); - PInt microseconds = divideNearest(inliningTarget, multiplyResult, denominator); + PInt microseconds; + Object saved = BoundaryCallContext.enter(frame, boundaryCallData); + try { + microseconds = divideNearest(inliningTarget, multiplyResult, denominator); + } finally { + BoundaryCallContext.exit(frame, boundaryCallData, saved); + } - return newNode.executeBuiltin(inliningTarget, 0, 0, microseconds, 0, 0, 0, 0); + return newNode.executeBuiltin(frame, inliningTarget, 0, 0, microseconds, 0, 0, 0, 0); } else { return PNotImplemented.NOT_IMPLEMENTED; } @@ -470,7 +473,8 @@ static Object div(VirtualFrame frame, Object left, Object right, @Cached TimeDeltaNodes.NewNode newNode, @Cached PyDeltaCheckNode checkLeft, @Cached PyDeltaCheckNode checkRight, - @Cached TemporalValueNodes.GetTimeDeltaValue readTimeDeltaValueNode) { + @Cached TemporalValueNodes.GetTimeDeltaValue readTimeDeltaValueNode, + @Cached("createFor($node)") BoundaryCallData boundaryCallData) { if (!checkLeft.execute(inliningTarget, left)) { return PNotImplemented.NOT_IMPLEMENTED; } @@ -482,8 +486,13 @@ static Object div(VirtualFrame frame, Object left, Object right, return trueDivideNode.execute(frame, microsecondsSelf, microsecondsOther); } else if (longCheckNode.execute(inliningTarget, right)) { Object microseconds = toMicroseconds(self, addNode, multiplyNode); - microseconds = divideNearest(inliningTarget, microseconds, right); - return newNode.executeBuiltin(inliningTarget, 0, 0, microseconds, 0, 0, 0, 0); + Object saved = BoundaryCallContext.enter(frame, boundaryCallData); + try { + microseconds = divideNearest(inliningTarget, microseconds, right); + } finally { + BoundaryCallContext.exit(frame, boundaryCallData, saved); + } + return newNode.executeBuiltin(frame, inliningTarget, 0, 0, microseconds, 0, 0, 0, 0); } else if (floatCheckNode.execute(inliningTarget, right)) { Object selfAsMicroseconds = toMicroseconds(self, addNode, multiplyNode); @@ -494,9 +503,15 @@ static Object div(VirtualFrame frame, Object left, Object right, Object denominator = tupleGetItem.execute(inliningTarget, ratioTuple, 0); Object multiplyResult = multiplyNode.execute(frame, selfAsMicroseconds, numerator); - PInt microseconds = divideNearest(inliningTarget, multiplyResult, denominator); + PInt microseconds; + Object saved = BoundaryCallContext.enter(frame, boundaryCallData); + try { + microseconds = divideNearest(inliningTarget, multiplyResult, denominator); + } finally { + BoundaryCallContext.exit(frame, boundaryCallData, saved); + } - return newNode.executeBuiltin(inliningTarget, 0, 0, microseconds, 0, 0, 0, 0); + return newNode.executeBuiltin(frame, inliningTarget, 0, 0, microseconds, 0, 0, 0, 0); } else { return PNotImplemented.NOT_IMPLEMENTED; } @@ -531,7 +546,7 @@ static Object div(VirtualFrame frame, Object left, Object right, } else if (longCheckNode.execute(inliningTarget, right)) { Object microseconds = toMicroseconds(self, addNode, multiplyNode); microseconds = floorDivideNode.execute(frame, microseconds, right); - return newNode.executeBuiltin(inliningTarget, 0, 0, microseconds, 0, 0, 0, 0); + return newNode.executeBuiltin(frame, inliningTarget, 0, 0, microseconds, 0, 0, 0, 0); } else { return PNotImplemented.NOT_IMPLEMENTED; } @@ -603,15 +618,15 @@ static Object mod(Object left, Object right, abstract static class AbsNode extends PythonUnaryBuiltinNode { @Specialization - static PTimeDelta abs(PTimeDelta selfObj, + static PTimeDelta abs(VirtualFrame frame, PTimeDelta selfObj, @Bind Node inliningTarget, @Cached TimeDeltaNodes.NewNode newNode, @Cached TemporalValueNodes.GetTimeDeltaValue readTimeDeltaValueNode) { TimeDeltaValue self = readTimeDeltaValueNode.execute(inliningTarget, selfObj); if (self.days >= 0) { - return newNode.executeBuiltin(inliningTarget, self.days, self.seconds, self.microseconds, 0, 0, 0, 0); + return newNode.executeBuiltin(frame, inliningTarget, self.days, self.seconds, self.microseconds, 0, 0, 0, 0); } else { - return newNode.executeBuiltin(inliningTarget, -self.days, -self.seconds, -self.microseconds, 0, 0, 0, 0); + return newNode.executeBuiltin(frame, inliningTarget, -self.days, -self.seconds, -self.microseconds, 0, 0, 0, 0); } } } @@ -621,12 +636,12 @@ static PTimeDelta abs(PTimeDelta selfObj, abstract static class PosNode extends PythonUnaryBuiltinNode { @Specialization - static PTimeDelta pos(PTimeDelta selfObj, + static PTimeDelta pos(VirtualFrame frame, PTimeDelta selfObj, @Bind Node inliningTarget, @Cached TimeDeltaNodes.NewNode newNode, @Cached TemporalValueNodes.GetTimeDeltaValue readTimeDeltaValueNode) { TimeDeltaValue self = readTimeDeltaValueNode.execute(inliningTarget, selfObj); - return newNode.executeBuiltin(inliningTarget, self.days, self.seconds, self.microseconds, 0, 0, 0, 0); + return newNode.executeBuiltin(frame, inliningTarget, self.days, self.seconds, self.microseconds, 0, 0, 0, 0); } } @@ -635,12 +650,12 @@ static PTimeDelta pos(PTimeDelta selfObj, abstract static class NegNode extends PythonUnaryBuiltinNode { @Specialization - static PTimeDelta neg(Object selfObj, + static PTimeDelta neg(VirtualFrame frame, Object selfObj, @Bind Node inliningTarget, @Cached TimeDeltaNodes.NewNode newNode, @Cached TemporalValueNodes.GetTimeDeltaValue readTimeDeltaValueNode) { TimeDeltaValue self = readTimeDeltaValueNode.execute(inliningTarget, selfObj); - return newNode.executeBuiltin(inliningTarget, -self.days, -self.seconds, -self.microseconds, 0, 0, 0, 0); + return newNode.executeBuiltin(frame, inliningTarget, -self.days, -self.seconds, -self.microseconds, 0, 0, 0, 0); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/datetime/TimeDeltaNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/datetime/TimeDeltaNodes.java index dd9aaee63a..c32604026f 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/datetime/TimeDeltaNodes.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/datetime/TimeDeltaNodes.java @@ -68,6 +68,7 @@ import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.util.CastToJavaBigIntegerNode; +import com.oracle.graal.python.runtime.ExecutionContext.BoundaryCallContext; import com.oracle.graal.python.runtime.IndirectCallData.BoundaryCallData; import com.oracle.graal.python.runtime.PythonContext; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; @@ -76,7 +77,7 @@ import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.GenerateUncached; import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.nodes.EncapsulatingNodeReference; +import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.object.Shape; @@ -89,10 +90,24 @@ public abstract static class NewNode extends Node { private static final int MAX_DAYS = 999_999_999; private static final int MIN_DAYS = -999_999_999; - public abstract Object execute(Node inliningTarget, Object cls, Object days, Object seconds, Object microseconds, Object milliseconds, Object minutes, Object hours, Object weeks); + public abstract Object execute(VirtualFrame frame, Node inliningTarget, Object cls, Object days, Object seconds, Object microseconds, Object milliseconds, Object minutes, Object hours, + Object weeks); + + /** + * Executes without access to the current Python frame. This overload may only be used when {@code cls} is + * {@link PythonBuiltinClassType} and all remaining arguments are known to be valid builtin values. + */ + public final Object execute(Node inliningTarget, Object cls, Object days, Object seconds, Object microseconds, Object milliseconds, Object minutes, Object hours, Object weeks) { + return execute(null, inliningTarget, cls, days, seconds, microseconds, milliseconds, minutes, hours, weeks); + } + + public final PTimeDelta executeBuiltin(VirtualFrame frame, Node inliningTarget, Object days, Object seconds, Object microseconds, Object milliseconds, Object minutes, Object hours, + Object weeks) { + return (PTimeDelta) execute(frame, inliningTarget, PythonBuiltinClassType.PTimeDelta, days, seconds, microseconds, milliseconds, minutes, hours, weeks); + } public final PTimeDelta executeBuiltin(Node inliningTarget, Object days, Object seconds, Object microseconds, Object milliseconds, Object minutes, Object hours, Object weeks) { - return (PTimeDelta) execute(inliningTarget, PythonBuiltinClassType.PTimeDelta, days, seconds, microseconds, milliseconds, minutes, hours, weeks); + return executeBuiltin(null, inliningTarget, days, seconds, microseconds, milliseconds, minutes, hours, weeks); } public static TimeDeltaNodes.NewNode getUncached() { @@ -100,18 +115,16 @@ public static TimeDeltaNodes.NewNode getUncached() { } @Specialization - static Object newTimeDelta(Node inliningTarget, Object cls, Object days, Object seconds, Object microseconds, Object milliseconds, Object minutes, Object hours, Object weeks, - @Cached TypeNodes.GetInstanceShape getInstanceShape) { + static Object newTimeDelta(VirtualFrame frame, Node inliningTarget, Object cls, Object days, Object seconds, Object microseconds, Object milliseconds, Object minutes, Object hours, + Object weeks, + @Cached TypeNodes.GetInstanceShape getInstanceShape, + @Cached("createFor($node)") BoundaryCallData callData) { Shape shape = getInstanceShape.execute(cls); - EncapsulatingNodeReference encapsulating = EncapsulatingNodeReference.getCurrent(); - Node encapsulatingNode = encapsulating.set(inliningTarget); + Object saved = BoundaryCallContext.enter(frame, callData); try { return createTimeDelta(inliningTarget, cls, shape, days, seconds, microseconds, milliseconds, minutes, hours, weeks); } finally { - // Some uncached nodes (e.g. PyLongFromDoubleNode and PyLongAsLongNode in - // Accumulator) may raise exceptions that are not connected to a current - // node. Set the current node manually. - encapsulating.set(encapsulatingNode); + BoundaryCallContext.exit(frame, callData, saved); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/datetime/TimeNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/datetime/TimeNodes.java index 59ebbe8753..2b9eeaf1fd 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/datetime/TimeNodes.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/datetime/TimeNodes.java @@ -69,6 +69,7 @@ import com.oracle.graal.python.nodes.PGuards; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.call.CallNode; +import com.oracle.graal.python.runtime.ExecutionContext.BoundaryCallContext; import com.oracle.graal.python.runtime.IndirectCallData.BoundaryCallData; import com.oracle.graal.python.runtime.PythonContext; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; @@ -78,7 +79,7 @@ import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.GenerateUncached; import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.nodes.EncapsulatingNodeReference; +import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.object.Shape; import com.oracle.truffle.api.strings.TruffleString; @@ -90,19 +91,21 @@ public class TimeNodes { @GenerateCached(false) public abstract static class NewNode extends Node { - public abstract Object execute(Node inliningTarget, Object cls, Object hour, Object minute, Object second, Object microsecond, Object tzInfo, Object fold); + public abstract Object execute(VirtualFrame frame, Node inliningTarget, Object cls, Object hour, Object minute, Object second, Object microsecond, Object tzInfo, Object fold); + + public final Object execute(Node inliningTarget, Object cls, Object hour, Object minute, Object second, Object microsecond, Object tzInfo, Object fold) { + return execute(null, inliningTarget, cls, hour, minute, second, microsecond, tzInfo, fold); + } @Specialization - static Object newTime(Node inliningTarget, Object cls, Object hourObject, Object minuteObject, Object secondObject, Object microsecondObject, Object tzInfoObject, Object foldObject) { - EncapsulatingNodeReference encapsulating = EncapsulatingNodeReference.getCurrent(); - Node encapsulatingNode = encapsulating.set(inliningTarget); + static Object newTime(VirtualFrame frame, Node inliningTarget, Object cls, Object hourObject, Object minuteObject, Object secondObject, Object microsecondObject, Object tzInfoObject, + Object foldObject, + @Cached("createFor($node)") BoundaryCallData callData) { + Object saved = BoundaryCallContext.enter(frame, callData); try { return newTimeBoundary(inliningTarget, cls, hourObject, minuteObject, secondObject, microsecondObject, tzInfoObject, foldObject); } finally { - // Some uncached nodes (e.g. PyLongAsLongNode) may raise exceptions - // that are not connected to a current node. Set the current node - // manually. - encapsulating.set(encapsulatingNode); + BoundaryCallContext.exit(frame, callData, saved); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/deque/DequeBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/deque/DequeBuiltins.java index 936428ccc3..eea0ba1d95 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/deque/DequeBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/deque/DequeBuiltins.java @@ -116,6 +116,8 @@ import com.oracle.graal.python.nodes.object.GetClassNode.GetPythonObjectClassNode; import com.oracle.graal.python.nodes.util.CannotCastException; import com.oracle.graal.python.nodes.util.CastToJavaIntExactNode; +import com.oracle.graal.python.runtime.ExecutionContext.BoundaryCallContext; +import com.oracle.graal.python.runtime.IndirectCallData.BoundaryCallData; import com.oracle.graal.python.runtime.exception.PException; import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; @@ -128,7 +130,6 @@ import com.oracle.truffle.api.dsl.NodeFactory; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.nodes.EncapsulatingNodeReference; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.profiles.InlinedBranchProfile; import com.oracle.truffle.api.profiles.InlinedConditionProfile; @@ -886,32 +887,36 @@ static PDequeIter doGeneric(PDeque self, abstract static class DequeReprNode extends PythonUnaryBuiltinNode { @Specialization - @TruffleBoundary - TruffleString repr(PDeque self) { + TruffleString repr(VirtualFrame frame, PDeque self, + @Cached("createFor($node)") BoundaryCallData boundaryCallData) { if (!getContext().reprEnter(self)) { return T_ELLIPSIS_IN_BRACKETS; } - EncapsulatingNodeReference ref = EncapsulatingNodeReference.getCurrent(); - Node outerNode = ref.set(this); + Object saved = BoundaryCallContext.enter(frame, boundaryCallData); try { - Object[] items = self.data.toArray(); - PList asList = PFactory.createList(PythonLanguage.get(null), items); - int maxLength = self.getMaxLength(); - TruffleStringBuilderUTF32 sb = TruffleStringBuilder.createUTF32(); - sb.appendStringUncached(GetNameNode.executeUncached(GetPythonObjectClassNode.executeUncached(self))); - sb.appendStringUncached(T_LPAREN); - sb.appendStringUncached(PyObjectStrAsTruffleStringNode.executeUncached(asList)); - if (maxLength != -1) { - sb.appendStringUncached(toTruffleStringUncached(", maxlen=")); - sb.appendIntNumberUncached(maxLength); - } - sb.appendStringUncached(T_RPAREN); - return sb.toStringUncached(); + return reprBoundary(self); } finally { - ref.set(outerNode); + BoundaryCallContext.exit(frame, boundaryCallData, saved); getContext().reprLeave(self); } } + + @TruffleBoundary + private static TruffleString reprBoundary(PDeque self) { + Object[] items = self.data.toArray(); + PList asList = PFactory.createList(PythonLanguage.get(null), items); + int maxLength = self.getMaxLength(); + TruffleStringBuilderUTF32 sb = TruffleStringBuilder.createUTF32(); + sb.appendStringUncached(GetNameNode.executeUncached(GetPythonObjectClassNode.executeUncached(self))); + sb.appendStringUncached(T_LPAREN); + sb.appendStringUncached(PyObjectStrAsTruffleStringNode.executeUncached(asList)); + if (maxLength != -1) { + sb.appendStringUncached(toTruffleStringUncached(", maxlen=")); + sb.appendIntNumberUncached(maxLength); + } + sb.appendStringUncached(T_RPAREN); + return sb.toStringUncached(); + } } @Builtin(name = J___REDUCE__, minNumOfPositionalArgs = 1) diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLCipherSelector.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLCipherSelector.java index 506c496a2a..dcd66d5077 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLCipherSelector.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLCipherSelector.java @@ -73,12 +73,18 @@ public static SSLCipher[] selectCiphers(Node node, String cipherList) { // The call fails when no <= TLSv1.2 ciphersuites get selected, regardless of TLSv1.3 // ciphersuites if (selected.isEmpty()) { - EncapsulatingNodeReference nodeRef = EncapsulatingNodeReference.getCurrent(); - Node prev = nodeRef.set(node); + EncapsulatingNodeReference nodeRef = null; + Node prev = null; + if (node != null && node.isAdoptable()) { + nodeRef = EncapsulatingNodeReference.getCurrent(); + prev = nodeRef.set(node); + } try { throw PConstructAndRaiseNode.raiseUncachedSSLError(ErrorMessages.NO_CIPHER_CAN_BE_SELECTED); } finally { - nodeRef.set(prev); + if (nodeRef != null) { + nodeRef.set(prev); + } } } // The API that CPython uses is meant only for setting <= TLSv1.2 ciphersuites, but it @@ -120,12 +126,18 @@ private static void selectSingle(Node node, String cipherString, List } else if (cipherString.startsWith("@SECLEVEL=")) { handleSecurityLevel(node, cipherString); } else { - EncapsulatingNodeReference nodeRef = EncapsulatingNodeReference.getCurrent(); - Node prev = nodeRef.set(node); + EncapsulatingNodeReference nodeRef = null; + Node prev = null; + if (node != null && node.isAdoptable()) { + nodeRef = EncapsulatingNodeReference.getCurrent(); + prev = nodeRef.set(node); + } try { throw PConstructAndRaiseNode.raiseUncachedSSLError(ErrorMessages.NO_CIPHER_CAN_BE_SELECTED); } finally { - nodeRef.set(prev); + if (nodeRef != null) { + nodeRef.set(prev); + } } } } else if (cipherString.equals("DEFAULT")) { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/ExecutionContext.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/ExecutionContext.java index 0ec5ce58a7..f36faa2a3c 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/ExecutionContext.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/ExecutionContext.java @@ -508,6 +508,12 @@ public abstract static class BoundaryCallContext { * access the exception state or current frame reference in the code that cannot take the * {@link VirtualFrame} as an argument. *

+ * Also pushes the {@link BoundaryCallData} node as {@link EncapsulatingNodeReference}. + * When a location is needed we normally traverse the AST up to the {@link BytecodeNode}, + * but behind Truffle boundary we may be executing uncached nodes disconnected from the AST, + * in such case by convention the last boundary transition location should be set as + * {@link EncapsulatingNodeReference}. + *

* See also {@link IndirectCalleeContext} for helper methods to make a call from a caller * without frame to a Python function. */