Slicing node to handle Array as well as polyglot objects

This commit is contained in:
Jaroslav Tulach 2023-05-11 08:10:22 +02:00
parent 415623dcb9
commit 9b1229fe20
3 changed files with 79 additions and 17 deletions

View File

@ -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);
}
}
}

View File

@ -1,5 +1,15 @@
package org.enso.interpreter.runtime.data; 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.CompilerDirectives;
import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.interop.InteropLibrary; import com.oracle.truffle.api.interop.InteropLibrary;
@ -130,13 +140,18 @@ public final class Array implements TruffleObject {
return allocate(0); return allocate(0);
} }
@Builtin.Method(name = "slice", description = "Returns a slice of this Array.") /**
@Builtin.Specialize * Takes a slice from an array like object.
@Builtin.WrapException(from = UnsupportedMessageException.class) *
public final Object slice(long start, long end, InteropLibrary interop) * @param self array like object
throws UnsupportedMessageException { * @param start start of the slice
var slice = ArraySlice.createOrNull(this, start, length(), end); * @param end end of the slice
return slice == null ? this : 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;
} }
/** /**

View File

@ -1,14 +1,5 @@
package org.enso.interpreter.runtime.error; 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.BaseNode.TailStatus;
import org.enso.interpreter.node.callable.IndirectInvokeMethodNode; import org.enso.interpreter.node.callable.IndirectInvokeMethodNode;
import org.enso.interpreter.node.callable.InvokeCallableNode.ArgumentsExecutionMode; 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.library.dispatch.TypesLibrary;
import org.enso.interpreter.runtime.state.State; 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. */ /** An exception type for user thrown panic exceptions. */
@ExportLibrary(value = InteropLibrary.class, delegateTo = "payload") @ExportLibrary(value = InteropLibrary.class, delegateTo = "payload")
@ExportLibrary(TypesLibrary.class) @ExportLibrary(TypesLibrary.class)
public class PanicException extends AbstractTruffleException { public final class PanicException extends AbstractTruffleException {
final Object payload; final Object payload;
String cacheMessage; String cacheMessage;