From 9b1229fe204189e17aa36a174cf748fe325da4c0 Mon Sep 17 00:00:00 2001 From: Jaroslav Tulach Date: Thu, 11 May 2023 08:10:22 +0200 Subject: [PATCH] Slicing node to handle Array as well as polyglot objects --- .../immutable/SliceArrayVectorNode.java | 44 +++++++++++++++++++ .../enso/interpreter/runtime/data/Array.java | 29 +++++++++--- .../runtime/error/PanicException.java | 23 +++++----- 3 files changed, 79 insertions(+), 17 deletions(-) create mode 100644 engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/immutable/SliceArrayVectorNode.java diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/immutable/SliceArrayVectorNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/immutable/SliceArrayVectorNode.java new file mode 100644 index 00000000000..151ee0b16e9 --- /dev/null +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/immutable/SliceArrayVectorNode.java @@ -0,0 +1,44 @@ +package org.enso.interpreter.node.expression.builtin.immutable; + +import org.enso.interpreter.dsl.BuiltinMethod; +import org.enso.interpreter.runtime.EnsoContext; +import org.enso.interpreter.runtime.data.Array; +import org.enso.interpreter.runtime.error.PanicException; + +import com.oracle.truffle.api.CompilerDirectives; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.interop.InteropLibrary; +import com.oracle.truffle.api.interop.UnsupportedMessageException; +import com.oracle.truffle.api.library.CachedLibrary; +import com.oracle.truffle.api.nodes.Node; + +@BuiltinMethod(type = "Array", name = "slice", description = "Returns a slice of this Array.") +public abstract class SliceArrayVectorNode extends Node { + SliceArrayVectorNode() {} + + public static SliceArrayVectorNode build() { + return SliceArrayVectorNodeGen.create(); + } + + abstract Object execute(Object self, long start, long end); + + @Specialization + Object executeArray(Array self, long start, long end) { + return Array.slice(self, start, end, self.length()); + } + + @Specialization(replaces = "executeArray") + Object executeArrayLike( + Object self, long start, long end, @CachedLibrary(limit = "3") InteropLibrary iop) { + try { + long len = iop.getArraySize(self); + return Array.slice(self, start, end, len); + } catch (UnsupportedMessageException ex) { + CompilerDirectives.transferToInterpreter(); + var ctx = EnsoContext.get(this); + var arrayType = ctx.getBuiltins().array(); + throw new PanicException( + ctx.getBuiltins().error().makeTypeError(arrayType, self, "self"), this); + } + } +} diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/Array.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/Array.java index 019c1ff6a0d..f6ed3908d80 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/Array.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/Array.java @@ -1,5 +1,15 @@ package org.enso.interpreter.runtime.data; +import java.util.Arrays; + +import org.enso.interpreter.dsl.Builtin; +import org.enso.interpreter.runtime.EnsoContext; +import org.enso.interpreter.runtime.error.Warning; +import org.enso.interpreter.runtime.error.WarningsLibrary; +import org.enso.interpreter.runtime.error.WithWarnings; +import org.enso.interpreter.runtime.library.dispatch.TypesLibrary; +import org.graalvm.collections.EconomicSet; + import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.interop.InteropLibrary; @@ -130,13 +140,18 @@ public final class Array implements TruffleObject { return allocate(0); } - @Builtin.Method(name = "slice", description = "Returns a slice of this Array.") - @Builtin.Specialize - @Builtin.WrapException(from = UnsupportedMessageException.class) - public final Object slice(long start, long end, InteropLibrary interop) - throws UnsupportedMessageException { - var slice = ArraySlice.createOrNull(this, start, length(), end); - return slice == null ? this : slice; + /** + * Takes a slice from an array like object. + * + * @param self array like object + * @param start start of the slice + * @param end end of the slice + * @param len the length of the array + * @return an array-like object representing the slice + */ + public static Object slice(Object self, long start, long end, long len) { + var slice = ArraySlice.createOrNull(self, start, len, end); + return slice == null ? self : slice; } /** diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/error/PanicException.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/error/PanicException.java index f74cd6947bf..d5f6423ef8a 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/error/PanicException.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/error/PanicException.java @@ -1,14 +1,5 @@ package org.enso.interpreter.runtime.error; -import com.oracle.truffle.api.CompilerDirectives; -import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.exception.AbstractTruffleException; -import com.oracle.truffle.api.interop.*; -import com.oracle.truffle.api.library.CachedLibrary; -import com.oracle.truffle.api.library.ExportLibrary; -import com.oracle.truffle.api.library.ExportMessage; -import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.source.SourceSection; import org.enso.interpreter.node.BaseNode.TailStatus; import org.enso.interpreter.node.callable.IndirectInvokeMethodNode; import org.enso.interpreter.node.callable.InvokeCallableNode.ArgumentsExecutionMode; @@ -23,10 +14,22 @@ import org.enso.interpreter.runtime.data.text.Text; import org.enso.interpreter.runtime.library.dispatch.TypesLibrary; import org.enso.interpreter.runtime.state.State; +import com.oracle.truffle.api.CompilerDirectives; +import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.exception.AbstractTruffleException; +import com.oracle.truffle.api.interop.ExceptionType; +import com.oracle.truffle.api.interop.InteropLibrary; +import com.oracle.truffle.api.interop.UnsupportedMessageException; +import com.oracle.truffle.api.library.CachedLibrary; +import com.oracle.truffle.api.library.ExportLibrary; +import com.oracle.truffle.api.library.ExportMessage; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.source.SourceSection; + /** An exception type for user thrown panic exceptions. */ @ExportLibrary(value = InteropLibrary.class, delegateTo = "payload") @ExportLibrary(TypesLibrary.class) -public class PanicException extends AbstractTruffleException { +public final class PanicException extends AbstractTruffleException { final Object payload; String cacheMessage;