Encapsulating array-like data and operations into a single package (#7544)

This commit is contained in:
Jaroslav Tulach 2023-08-15 13:00:47 +02:00 committed by GitHub
parent 8541a9e1ac
commit 7a272ec152
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
89 changed files with 1415 additions and 1088 deletions

View File

@ -18,6 +18,7 @@ import project.Errors.Unimplemented.Unimplemented
import project.Meta
import project.Nothing.Nothing
import project.Panic.Panic
import project.Internal.Array_Like_Helpers
from project.Data.Boolean import Boolean, False, True
from project.Data.Index_Sub_Range import Index_Sub_Range
from project.Data.Range.Extensions import all
@ -42,7 +43,7 @@ type Array
[1, 2, 3].to_array.at -1 == 3
at : Integer -> Any ! Index_Out_Of_Bounds
at self index = @Builtin_Method "Array.at"
at self index = Array_Like_Helpers.at self index
## Returns the number of elements stored in this array.
@ -51,7 +52,7 @@ type Array
[1, 2, 3, 4].to_array.length
length : Integer
length self = @Builtin_Method "Array.length"
length self = Array_Like_Helpers.length self
## Identity.
This method is implemented purely for completeness with the runtime's

View File

@ -3,6 +3,8 @@ import project.Data.Array.Array
import project.Data.Numbers.Integer
import project.Errors.Illegal_Argument.Illegal_Argument
import project.Internal.Array_Like_Helpers
## PRIVATE
A helper type used for creating an array from a length and a callback
providing its elements.
@ -12,8 +14,10 @@ import project.Errors.Illegal_Argument.Illegal_Argument
type returned from polyglot calls to other languages. The most common
use-case for it is to pass it to `Vector.from_polyglot_array` to create a
vector backed by such custom storage.
@Builtin_Type
type Array_Proxy
## PRIVATE
Value ignore
## PRIVATE
ADVANCED
Creates a new `Array_Proxy` from a length and a callback.
@ -28,16 +32,7 @@ type Array_Proxy
Vector.from_polyglot_array (Array_Proxy.new 10000000 (i -> i))
new : Integer -> (Integer -> Any) -> Array
new length at = Illegal_Argument.handle_java_exception <|
Array_Proxy.new_builtin length at
## PRIVATE
The builtin cannot throw `Illegal_Argument` as that type cannot be a
builtin, because they do not support default arguments in constructors.
So a wrapper is used which will translate a Java exception into the Enso
one. This indirection may be removed once the following story is done:
https://www.pivotaltracker.com/n/projects/2539304/stories/183817602
new_builtin : Integer -> (Integer -> Any) -> Array
new_builtin length at = @Builtin_Method "Array_Proxy.new_builtin"
Array_Like_Helpers.new_array_proxy_builtin length at
## PRIVATE
ADVANCED
@ -45,4 +40,4 @@ type Array_Proxy
methods.
from_proxy_object : Any -> Array
from_proxy_object proxy =
Array_Proxy.new proxy.length proxy.at
Array_Like_Helpers.new_array_proxy_builtin proxy.length proxy.at

View File

@ -23,6 +23,8 @@ import project.Nothing.Nothing
import project.Panic.Panic
import project.Random
import project.Warning.Warning
import project.Internal.Array_Like_Helpers
from project.Data.Boolean import Boolean, False, True
from project.Data.Filter_Condition import unify_condition_or_predicate, unify_condition_predicate_or_element
from project.Data.Index_Sub_Range import drop_helper, Index_Sub_Range, take_helper
@ -30,7 +32,6 @@ from project.Data.Ordering import all
from project.Data.Range.Extensions import all
polyglot java import java.lang.IndexOutOfBoundsException
polyglot java import org.enso.base.Array_Builder
## The basic, immutable, vector type.
A vector allows to store an arbitrary number of elements, in linear memory.
@ -69,7 +70,7 @@ type Vector a
Vector.new my_vec.length (ix -> my_vec.at ix)
new : Integer -> (Integer -> Any) -> Vector Any
new length constructor = @Builtin_Method "Vector.new"
new length constructor = Array_Like_Helpers.vector_from_function length constructor
## PRIVATE
ADVANCED
@ -161,7 +162,7 @@ type Vector a
## PRIVATE
ADVANCED
Copies content of a vector into an Array.
to_array self = @Builtin_Method "Vector.to_array"
to_array self = Array_Like_Helpers.vector_to_array self
## Returns the number of elements stored in this vector.
@ -170,7 +171,7 @@ type Vector a
[1, 2, 3, 4].length
length : Integer
length self = @Builtin_Method "Vector.length"
length self = Array_Like_Helpers.length self
## Gets an element from the vector at a specified index (0-based).
@ -189,7 +190,7 @@ type Vector a
[1, 2, 3].at -1 == 3
at : Integer -> Any ! Index_Out_Of_Bounds
at self index = @Builtin_Method "Vector.at"
at self index = Array_Like_Helpers.at self index
## Gets an element from the vector at a specified index (0-based).
If the index is invalid then `if_missing` is returned.
@ -1045,7 +1046,7 @@ type Builder
Vector.new_builder
new : Integer -> Builder
new (capacity=10) = Builder.Value (Array_Builder.newBuilder capacity)
new (capacity=10) = Builder.Value (Array_Like_Helpers.new_vector_builder capacity)
## Checks if this builder is empty.
is_empty : Boolean

View File

@ -0,0 +1,22 @@
import project.Any.Any
import project.Data.Array.Array
import project.Data.Vector.Vector
import project.Data.Numbers.Integer
new_array_proxy_builtin : Integer -> (Integer -> Any) -> Array
new_array_proxy_builtin length at = @Builtin_Method "Array_Like_Helpers.new_array_proxy_builtin"
new_vector_builder : Integer -> Any
new_vector_builder capacity = @Builtin_Method "Array_Like_Helpers.new_vector_builder"
length : (Array | Vector) -> Integer
length array_like = @Builtin_Method "Array_Like_Helpers.length"
at : (Array | Vector) -> Integer -> Any
at array_like index = @Builtin_Method "Array_Like_Helpers.at"
vector_to_array : (Vector | Array) -> Array
vector_to_array array_like = @Builtin_Method "Array_Like_Helpers.vector_to_array"
vector_from_function : Integer -> (Integer -> Any) -> Vector Any
vector_from_function length constructor = @Builtin_Method "Array_Like_Helpers.vector_from_function"

View File

@ -16,7 +16,7 @@ import project.Warning.Warning
from project.Data.Boolean import Boolean, False, True
from project.Data.Text.Extensions import all
polyglot java import org.enso.base.Array_Builder
polyglot java import org.enso.base.Array_Utils
## Writes (or appends) the text to the specified file using the supplied
encoding. The behavior specified in the `existing_file` parameter will be
@ -98,7 +98,7 @@ Vector.write_bytes : (File|Text) -> Existing_File_Behavior -> File ! Illegal_Arg
Vector.write_bytes self path on_existing_file=Existing_File_Behavior.Backup =
Panic.catch Unsupported_Argument_Types handler=(_ -> Error.throw (Illegal_Argument.Error "Only Vectors consisting of bytes (integers in the range from -128 to 127) are supported by the `write_bytes` method.")) <|
## Convert to a byte array before writing - and fail early if there is any problem.
byte_array = Array_Builder.ensureByteArray self
byte_array = Array_Utils.ensureByteArray self
file = File.new path
r = on_existing_file.write file stream->

View File

@ -12,8 +12,8 @@ import java.util.Arrays;
* A primitive boxed array type to be used only in EPB.
*
* <p>{@link ReadOnlyArray} is essentially a stripped-down, read-only, version of {@link
* org.enso.interpreter.runtime.data.Array}, used for passing arguments. The latter cannot be used
* in EPB because EPB is a dependency of runtime.
* org.enso.interpreter.runtime.data.vector.Array}, used for passing arguments. The latter cannot be
* used in EPB because EPB is a dependency of runtime.
*/
@ExportLibrary(InteropLibrary.class)
public final class ReadOnlyArray implements TruffleObject {

View File

@ -1,8 +1,6 @@
package org.enso.interpreter.bench.benchmarks.semantic;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Paths;
@ -10,10 +8,10 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import org.enso.interpreter.test.TestBase;
import org.enso.polyglot.MethodNames.Module;
import org.graalvm.polyglot.Context;
import org.graalvm.polyglot.Source;
import org.graalvm.polyglot.Value;
import org.graalvm.polyglot.io.IOAccess;
import org.openjdk.jmh.annotations.Benchmark;

View File

@ -16,12 +16,15 @@ import com.oracle.truffle.api.library.ExportMessage;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.nodes.NodeInfo;
import com.oracle.truffle.api.source.SourceSection;
import org.enso.interpreter.runtime.callable.function.Function;
import org.enso.interpreter.runtime.tag.IdentifiedTag;
import java.util.Arrays;
import java.util.UUID;
import org.enso.interpreter.node.ClosureRootNode;
import org.enso.interpreter.runtime.data.EnsoObject;
import org.enso.interpreter.runtime.tag.AvoidIdInstrumentationTag;
/**
@ -56,7 +59,7 @@ public class FunctionCallInstrumentationNode extends Node implements Instrumenta
/** A simple value class for function call information. */
@ExportLibrary(InteropLibrary.class)
public static final class FunctionCall implements TruffleObject {
public static final class FunctionCall implements EnsoObject {
private final Function function;
private final Object state;
private final @CompilerDirectives.CompilationFinal(dimensions = 1) Object[] arguments;

View File

@ -1,8 +1,7 @@
package org.enso.interpreter.node.callable;
import org.enso.interpreter.node.ExpressionNode;
import org.enso.interpreter.runtime.data.Array;
import org.enso.interpreter.runtime.data.Vector;
import org.enso.interpreter.runtime.data.vector.ArrayLikeHelpers;
import org.enso.interpreter.runtime.error.PanicSentinel;
import com.oracle.truffle.api.frame.VirtualFrame;
@ -43,6 +42,6 @@ public class SequenceLiteralNode extends ExpressionNode {
throw sentinel;
}
}
return Vector.fromArray(new Array(itemValues));
return ArrayLikeHelpers.asVectorWithCheckAt(itemValues);
}
}

View File

@ -1,10 +1,11 @@
package org.enso.interpreter.node.controlflow.caseexpr;
import com.oracle.truffle.api.interop.TruffleObject;
import com.oracle.truffle.api.nodes.Node;
import org.enso.interpreter.runtime.EnsoContext;
record BranchResult(boolean isMatched, Object result) implements TruffleObject {
import org.enso.interpreter.runtime.EnsoContext;
import org.enso.interpreter.runtime.data.EnsoObject;
record BranchResult(boolean isMatched, Object result) implements EnsoObject {
static BranchResult failure(Node node) {
return new BranchResult(false, EnsoContext.get(node).getBuiltins().nothing());
}

View File

@ -6,7 +6,7 @@ import org.enso.interpreter.dsl.BuiltinMethod;
import org.enso.interpreter.node.expression.builtin.runtime.GetStackTraceNode;
import org.enso.interpreter.runtime.EnsoContext;
import org.enso.interpreter.runtime.builtin.Builtins;
import org.enso.interpreter.runtime.data.Array;
import org.enso.interpreter.runtime.data.EnsoObject;
import org.enso.interpreter.runtime.error.PanicException;
@BuiltinMethod(
@ -14,7 +14,7 @@ import org.enso.interpreter.runtime.error.PanicException;
name = "primitive_get_attached_stack_trace",
description = "Gets the stack trace attached to the throwable.")
public class GetAttachedStackTraceNode extends Node {
Array execute(@AcceptsError Object error) {
EnsoObject execute(@AcceptsError Object error) {
if (error instanceof Throwable) {
return GetStackTraceNode.stackTraceToArray((Throwable) error);
} else {

View File

@ -1,43 +1,39 @@
package org.enso.interpreter.node.expression.builtin.immutable;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.interop.InteropLibrary;
import com.oracle.truffle.api.interop.InvalidArrayIndexException;
import com.oracle.truffle.api.interop.UnsupportedMessageException;
import com.oracle.truffle.api.nodes.Node;
import org.enso.interpreter.dsl.BuiltinMethod;
import org.enso.interpreter.node.expression.builtin.interop.syntax.HostValueToEnsoNode;
import org.enso.interpreter.runtime.EnsoContext;
import org.enso.interpreter.runtime.data.Vector;
import org.enso.interpreter.runtime.data.vector.ArrayLikeAtNode;
import org.enso.interpreter.runtime.data.vector.ArrayLikeLengthNode;
import org.enso.interpreter.runtime.error.DataflowError;
import org.enso.interpreter.runtime.error.WarningsLibrary;
@BuiltinMethod(
type = "Vector",
type = "Array_Like_Helpers",
name = "at",
description = "Returns an element of Vector at the specified index.")
public class AtVectorNode extends Node {
private @Child InteropLibrary interop = InteropLibrary.getFactory().createDispatched(3);
private @Child WarningsLibrary warnings = WarningsLibrary.getFactory().createDispatched(3);
private @Child HostValueToEnsoNode convert = HostValueToEnsoNode.build();
private @Child ArrayLikeAtNode at = ArrayLikeAtNode.create();
private @Child ArrayLikeLengthNode length;
Object execute(Vector self, long index) {
Object execute(Object arrayLike, long index) {
try {
return readElement(self, index);
} catch (UnsupportedMessageException e) {
CompilerDirectives.transferToInterpreter();
throw new IllegalStateException(e);
long actualIndex = index < 0 ? index + len(arrayLike) : index;
return at.executeAt(arrayLike, actualIndex);
} catch (InvalidArrayIndexException e) {
var len = len(arrayLike);
var ctx = EnsoContext.get(this);
var payload = ctx.getBuiltins().error().makeIndexOutOfBounds(index, len);
return DataflowError.withoutTrace(payload, this);
}
}
private Object readElement(Vector self, long index) throws UnsupportedMessageException {
try {
long actualIndex = index < 0 ? index + self.length(interop) : index;
return self.readArrayElement(actualIndex, interop, warnings, convert);
} catch (InvalidArrayIndexException e) {
EnsoContext ctx = EnsoContext.get(this);
return DataflowError.withoutTrace(
ctx.getBuiltins().error().makeIndexOutOfBounds(index, self.length(interop)), this);
private long len(Object arrayLike) {
if (length == null) {
CompilerDirectives.transferToInterpreterAndInvalidate();
length = insert(ArrayLikeLengthNode.create());
}
return length.executeLength(arrayLike);
}
}

View File

@ -2,20 +2,17 @@ package org.enso.interpreter.node.expression.builtin.immutable;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.Cached.Shared;
import com.oracle.truffle.api.dsl.Fallback;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.interop.InteropLibrary;
import com.oracle.truffle.api.interop.InvalidArrayIndexException;
import com.oracle.truffle.api.interop.UnsupportedMessageException;
import com.oracle.truffle.api.library.CachedLibrary;
import com.oracle.truffle.api.nodes.Node;
import org.enso.interpreter.dsl.BuiltinMethod;
import org.enso.interpreter.node.expression.builtin.mutable.CopyNode;
import org.enso.interpreter.runtime.EnsoContext;
import org.enso.interpreter.runtime.builtin.Builtins;
import org.enso.interpreter.runtime.data.Array;
import org.enso.interpreter.runtime.data.Vector;
import org.enso.interpreter.runtime.data.EnsoObject;
import org.enso.interpreter.runtime.data.vector.ArrayLikeAtNode;
import org.enso.interpreter.runtime.data.vector.ArrayLikeCopyToArrayNode;
import org.enso.interpreter.runtime.data.vector.ArrayLikeHelpers;
import org.enso.interpreter.runtime.data.vector.ArrayLikeLengthNode;
import org.enso.interpreter.runtime.error.PanicException;
@BuiltinMethod(
@ -28,87 +25,41 @@ public abstract class FlattenVectorNode extends Node {
return FlattenVectorNodeGen.create();
}
abstract Vector execute(Object self);
abstract EnsoObject execute(Object self);
@Specialization
Vector fromVector(
Vector self,
@Shared("copyNode") @Cached CopyNode copyNode,
@Shared("interop") @CachedLibrary(limit = "3") InteropLibrary interop) {
try {
return flatten(self.toArray(), copyNode, interop);
} catch (UnsupportedMessageException e) {
CompilerDirectives.transferToInterpreter();
Builtins builtins = EnsoContext.get(this).getBuiltins();
throw new PanicException(
builtins.error().makeTypeError(builtins.vector(), self, "self"), this);
}
}
@Specialization
Vector fromArray(
Array self,
@Shared("copyNode") @Cached CopyNode copyNode,
@Shared("interop") @CachedLibrary(limit = "3") InteropLibrary interop) {
try {
return flatten(self, copyNode, interop);
} catch (UnsupportedMessageException e) {
throw unsupportedException(self);
}
}
@Specialization(guards = "interop.hasArrayElements(self)")
Vector fromArrayLike(
EnsoObject flattenAnything(
Object self,
@Shared("copyNode") @Cached CopyNode copyNode,
@Shared("interop") @CachedLibrary(limit = "3") InteropLibrary interop) {
@Cached ArrayLikeCopyToArrayNode copyNode,
@Cached ArrayLikeLengthNode lengthNode,
@Cached ArrayLikeAtNode atNode) {
return flatten(self, copyNode, lengthNode, atNode);
}
private EnsoObject flatten(
Object storage,
ArrayLikeCopyToArrayNode copyNode,
ArrayLikeLengthNode lengthNode,
ArrayLikeAtNode atNode) {
try {
return flatten(self, copyNode, interop);
} catch (UnsupportedMessageException e) {
throw unsupportedException(self);
}
}
@Fallback
Vector fromUnknown(Object self) {
throw unsupportedException(self);
}
private PanicException unsupportedException(Object self) {
CompilerDirectives.transferToInterpreter();
var ctx = EnsoContext.get(this);
var err = ctx.getBuiltins().error().makeTypeError("polyglot array", self, "self");
throw new PanicException(err, this);
}
private Vector flatten(Object storage, CopyNode copyNode, InteropLibrary interop)
throws UnsupportedMessageException {
try {
long length = interop.getArraySize(storage);
long length = lengthNode.executeLength(storage);
long flattened_length = 0;
for (long i = 0; i < length; i++) {
var item = interop.readArrayElement(storage, i);
if (!interop.hasArrayElements(item)) {
CompilerDirectives.transferToInterpreter();
Builtins builtins = EnsoContext.get(this).getBuiltins();
throw new PanicException(
builtins.error().makeTypeError(builtins.vector(), item, "[" + i + "]"), this);
}
flattened_length += interop.getArraySize(item);
var item = atNode.executeAt(storage, i);
flattened_length += lengthNode.executeLength(item);
}
Array result = Array.allocate(flattened_length);
var result = ArrayLikeHelpers.allocate(flattened_length);
long current_index = 0;
for (long i = 0; i < length; i++) {
var item = interop.readArrayElement(storage, i);
var item_length = interop.getArraySize(item);
var item = atNode.executeAt(storage, i);
var item_length = lengthNode.executeLength(item);
copyNode.execute(item, 0, result, current_index, item_length);
current_index += item_length;
}
return Vector.fromArray(result);
return ArrayLikeHelpers.asVectorFromArray(result);
} catch (InvalidArrayIndexException e) {
CompilerDirectives.transferToInterpreter();
Builtins builtins = EnsoContext.get(this).getBuiltins();

View File

@ -1,15 +1,13 @@
package org.enso.interpreter.node.expression.builtin.immutable;
import com.oracle.truffle.api.dsl.*;
import com.oracle.truffle.api.interop.InteropLibrary;
import com.oracle.truffle.api.library.CachedLibrary;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.Fallback;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.nodes.Node;
import org.enso.interpreter.dsl.BuiltinMethod;
import org.enso.interpreter.node.expression.builtin.mutable.CoerceArrayNode;
import org.enso.interpreter.runtime.EnsoContext;
import org.enso.interpreter.runtime.data.Array;
import org.enso.interpreter.runtime.data.Vector;
import org.enso.interpreter.runtime.error.PanicException;
import org.enso.interpreter.runtime.data.EnsoObject;
import org.enso.interpreter.runtime.data.vector.ArrayLikeCoerceToArrayNode;
import org.enso.interpreter.runtime.data.vector.ArrayLikeHelpers;
@BuiltinMethod(
type = "Vector",
@ -21,29 +19,19 @@ public abstract class FromArrayBuiltinVectorNode extends Node {
return FromArrayBuiltinVectorNodeGen.create();
}
abstract Vector execute(Object arr);
abstract EnsoObject execute(Object arr);
@Specialization
Vector fromVector(Vector arr) {
return arr;
}
@Specialization(guards = "interop.hasArrayElements(arr)")
Vector fromArrayLikeObject(
Object arr,
@Cached CoerceArrayNode coerce,
@CachedLibrary(limit = "3") InteropLibrary interop) {
return Vector.fromArray(new Array(coerce.execute(arr)));
@Specialization(guards = "isImmutableArrayLike(arr)")
EnsoObject fromVector(Object arr) {
return (EnsoObject) arr;
}
@Fallback
Vector fromUnknown(Object arr) {
throw unsupportedException(arr);
EnsoObject fromArrayLikeObject(Object arr, @Cached ArrayLikeCoerceToArrayNode coerce) {
return ArrayLikeHelpers.asVectorWithCheckAt(coerce.execute(arr));
}
private PanicException unsupportedException(Object arr) {
var ctx = EnsoContext.get(this);
var err = ctx.getBuiltins().error().makeTypeError("polyglot array", arr, "array");
throw new PanicException(err, this);
static boolean isImmutableArrayLike(Object obj) {
return ArrayLikeHelpers.isImmutable(obj);
}
}

View File

@ -6,7 +6,8 @@ import com.oracle.truffle.api.library.CachedLibrary;
import com.oracle.truffle.api.nodes.Node;
import org.enso.interpreter.dsl.BuiltinMethod;
import org.enso.interpreter.runtime.EnsoContext;
import org.enso.interpreter.runtime.data.Vector;
import org.enso.interpreter.runtime.data.EnsoObject;
import org.enso.interpreter.runtime.data.vector.ArrayLikeHelpers;
import org.enso.interpreter.runtime.error.PanicException;
@BuiltinMethod(
@ -21,16 +22,16 @@ public abstract class FromPolyglotArrayBuiltinVectorNode extends Node {
return FromPolyglotArrayBuiltinVectorNodeGen.create();
}
abstract Vector execute(Object arr);
abstract EnsoObject execute(Object arr);
@Specialization(guards = "interop.hasArrayElements(arr)")
Vector doObject(Object arr, @CachedLibrary(limit = "1") InteropLibrary interop) {
return Vector.fromArray(arr);
EnsoObject doObject(Object arr, @CachedLibrary(limit = "1") InteropLibrary interop) {
return ArrayLikeHelpers.asVectorFromArray(arr);
}
@Fallback
Vector doOther(Object arr) {
EnsoContext ctx = EnsoContext.get(this);
EnsoObject doOther(Object arr) {
var ctx = EnsoContext.get(this);
throw new PanicException(
ctx.getBuiltins().error().makeTypeError("polyglot array", arr, "array"), this);
}

View File

@ -1,19 +1,13 @@
package org.enso.interpreter.node.expression.builtin.immutable;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.Cached.Shared;
import com.oracle.truffle.api.dsl.Fallback;
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;
import org.enso.interpreter.dsl.BuiltinMethod;
import org.enso.interpreter.node.expression.builtin.mutable.CopyNode;
import org.enso.interpreter.runtime.EnsoContext;
import org.enso.interpreter.runtime.data.Array;
import org.enso.interpreter.runtime.data.Vector;
import org.enso.interpreter.runtime.error.PanicException;
import org.enso.interpreter.runtime.data.EnsoObject;
import org.enso.interpreter.runtime.data.vector.ArrayLikeCopyToArrayNode;
import org.enso.interpreter.runtime.data.vector.ArrayLikeHelpers;
import org.enso.interpreter.runtime.data.vector.ArrayLikeLengthNode;
@BuiltinMethod(
type = "Vector",
@ -25,91 +19,21 @@ public abstract class InsertBuiltinVectorNode extends Node {
return InsertBuiltinVectorNodeGen.create();
}
abstract Vector execute(Object vec, long index, Object values);
abstract EnsoObject execute(Object vec, long index, Object values);
@Specialization
Vector fromVector(
Vector vec,
long index,
Vector values,
@Shared("copyNode") @Cached CopyNode copyNode,
@Shared("interop") @CachedLibrary(limit = "3") InteropLibrary interop) {
return insertBuiltin(vec.toArray(), index, values.toArray(), copyNode, interop);
}
@Specialization
Vector fromArray(
Array vec,
long index,
Vector values,
@Shared("copyNode") @Cached CopyNode copyNode,
@Shared("interop") @CachedLibrary(limit = "3") InteropLibrary interop) {
return insertBuiltin(vec, index, values.toArray(), copyNode, interop);
}
@Specialization(guards = "interop.hasArrayElements(vec)")
Vector fromArrayLike(
Object vec,
long index,
Vector values,
@Shared("copyNode") @Cached CopyNode copyNode,
@Shared("interop") @CachedLibrary(limit = "3") InteropLibrary interop) {
return insertBuiltin(vec, index, values.toArray(), copyNode, interop);
}
@Specialization(guards = "interop.hasArrayElements(values)")
Vector fromVectorWithArrayLikeObject(
Vector vec,
long index,
Object values,
@Shared("copyNode") @Cached CopyNode copyNode,
@Shared("interop") @CachedLibrary(limit = "3") InteropLibrary interop) {
return insertBuiltin(vec.toArray(), index, values, copyNode, interop);
}
@Specialization(guards = "interop.hasArrayElements(values)")
Vector fromArrayWithArrayLikeObject(
Array vec,
long index,
Object values,
@Shared("copyNode") @Cached CopyNode copyNode,
@Shared("interop") @CachedLibrary(limit = "3") InteropLibrary interop) {
return insertBuiltin(vec, index, values, copyNode, interop);
}
@Specialization(guards = {"interop.hasArrayElements(vec)", "interop.hasArrayElements(values)"})
Vector fromArrayLikeWithArrayLikeObject(
EnsoObject fromObject(
Object vec,
long index,
Object values,
@Shared("copyNode") @Cached CopyNode copyNode,
@Shared("interop") @CachedLibrary(limit = "3") InteropLibrary interop) {
return insertBuiltin(vec, index, values, copyNode, interop);
}
@Fallback
Vector fromUnknown(Object vec, long index, Object values) {
throw unsupportedException(values);
}
private PanicException unsupportedException(Object values) {
var ctx = EnsoContext.get(this);
var err = ctx.getBuiltins().error().makeTypeError("polyglot array", values, "values");
throw new PanicException(err, this);
}
private Vector insertBuiltin(
Object current, long index, Object values, CopyNode copyNode, InteropLibrary interop) {
try {
long currentLength = interop.getArraySize(current);
long valuesLength = interop.getArraySize(values);
Array result = Array.allocate(currentLength + valuesLength);
copyNode.execute(current, 0, result, 0, index);
copyNode.execute(values, 0, result, index, valuesLength);
copyNode.execute(current, index, result, index + valuesLength, currentLength - index);
return Vector.fromArray(result);
} catch (UnsupportedMessageException e) {
throw unsupportedException(values);
}
@Cached ArrayLikeCopyToArrayNode copyNode,
@Cached ArrayLikeLengthNode lengthNode) {
long currentLength = lengthNode.executeLength(vec);
long valuesLength = lengthNode.executeLength(values);
var result = ArrayLikeHelpers.allocate(currentLength + valuesLength);
copyNode.execute(vec, 0, result, 0, index);
copyNode.execute(values, 0, result, index, valuesLength);
copyNode.execute(vec, index, result, index + valuesLength, currentLength - index);
return ArrayLikeHelpers.asVectorFromArray(result);
}
}

View File

@ -0,0 +1,17 @@
package org.enso.interpreter.node.expression.builtin.immutable;
import com.oracle.truffle.api.nodes.Node;
import org.enso.interpreter.dsl.BuiltinMethod;
import org.enso.interpreter.runtime.data.vector.ArrayLikeLengthNode;
@BuiltinMethod(
type = "Array_Like_Helpers",
name = "length",
description = "Returns the length of this Vector.")
public class LengthVectorNode extends Node {
@Child ArrayLikeLengthNode length = ArrayLikeLengthNode.create();
long execute(Object arrayLike) {
return length.executeLength(arrayLike);
}
}

View File

@ -1,21 +1,13 @@
package org.enso.interpreter.node.expression.builtin.immutable;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.Cached.Shared;
import com.oracle.truffle.api.dsl.Fallback;
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;
import org.enso.interpreter.dsl.BuiltinMethod;
import org.enso.interpreter.node.expression.builtin.mutable.CopyNode;
import org.enso.interpreter.runtime.EnsoContext;
import org.enso.interpreter.runtime.builtin.Builtins;
import org.enso.interpreter.runtime.data.Array;
import org.enso.interpreter.runtime.data.Vector;
import org.enso.interpreter.runtime.error.PanicException;
import org.enso.interpreter.runtime.data.EnsoObject;
import org.enso.interpreter.runtime.data.vector.ArrayLikeCopyToArrayNode;
import org.enso.interpreter.runtime.data.vector.ArrayLikeHelpers;
import org.enso.interpreter.runtime.data.vector.ArrayLikeLengthNode;
@BuiltinMethod(
type = "Vector",
@ -27,69 +19,19 @@ public abstract class RemoveAtVectorNode extends Node {
return RemoveAtVectorNodeGen.create();
}
abstract Vector execute(Object vec, long index);
abstract EnsoObject execute(Object vec, long index);
@Specialization
Vector fromVector(
Vector vec,
EnsoObject removeAtIndex(
Object storage,
long index,
@Shared("copyNode") @Cached CopyNode copyNode,
@Shared("interop") @CachedLibrary(limit = "3") InteropLibrary interop) {
try {
return removeAtIndex(vec.toArray(), index, copyNode, interop);
} catch (UnsupportedMessageException e) {
CompilerDirectives.transferToInterpreter();
Builtins builtins = EnsoContext.get(this).getBuiltins();
throw new PanicException(builtins.error().makeTypeError(builtins.vector(), vec, "vec"), this);
}
}
@Specialization
Vector fromArray(
Array vec,
long index,
@Shared("copyNode") @Cached CopyNode copyNode,
@Shared("interop") @CachedLibrary(limit = "3") InteropLibrary interop) {
try {
return removeAtIndex(vec, index, copyNode, interop);
} catch (UnsupportedMessageException e) {
throw unsupportedException(vec);
}
}
@Specialization(guards = "interop.hasArrayElements(vec)")
Vector fromArrayLike(
Object vec,
long index,
@Shared("copyNode") @Cached CopyNode copyNode,
@Shared("interop") @CachedLibrary(limit = "3") InteropLibrary interop) {
try {
return removeAtIndex(vec, index, copyNode, interop);
} catch (UnsupportedMessageException e) {
throw unsupportedException(vec);
}
}
@Fallback
Vector fromUnknown(Object vec, long index) {
throw unsupportedException(vec);
}
private PanicException unsupportedException(Object vec) {
CompilerDirectives.transferToInterpreter();
var ctx = EnsoContext.get(this);
var err = ctx.getBuiltins().error().makeTypeError("polyglot array", vec, "vec");
throw new PanicException(err, this);
}
private Vector removeAtIndex(
Object storage, long index, CopyNode copyArrayNode, InteropLibrary interop)
throws UnsupportedMessageException {
long length = interop.getArraySize(storage);
@Cached ArrayLikeCopyToArrayNode copyArrayNode,
@Cached ArrayLikeLengthNode lengthNode) {
long length = lengthNode.executeLength(storage);
long actualIndex = index < 0 ? index + length : index;
Array array = Array.allocate(length - 1);
var array = ArrayLikeHelpers.allocate(length - 1);
copyArrayNode.execute(storage, 0, array, 0, actualIndex);
copyArrayNode.execute(storage, actualIndex + 1, array, actualIndex, length - actualIndex - 1);
return Vector.fromArray(array);
return ArrayLikeHelpers.asVectorFromArray(array);
}
}

View File

@ -1,66 +1,22 @@
package org.enso.interpreter.node.expression.builtin.immutable;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.dsl.Cached.Shared;
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;
import org.enso.interpreter.dsl.BuiltinMethod;
import org.enso.interpreter.runtime.EnsoContext;
import org.enso.interpreter.runtime.data.Array;
import org.enso.interpreter.runtime.data.Vector;
import org.enso.interpreter.runtime.error.PanicException;
import org.enso.interpreter.runtime.data.vector.ArrayLikeHelpers;
import org.enso.interpreter.runtime.data.vector.ArrayLikeLengthNode;
@BuiltinMethod(type = "Vector", name = "slice", description = "Returns a slice of this Vector.")
public abstract class SliceArrayVectorNode extends Node {
SliceArrayVectorNode() {}
public final class SliceArrayVectorNode extends Node {
private @Child ArrayLikeLengthNode lengthNode = ArrayLikeLengthNode.create();
private SliceArrayVectorNode() {}
public static SliceArrayVectorNode build() {
return SliceArrayVectorNodeGen.create();
return new SliceArrayVectorNode();
}
abstract Object execute(Object self, long start, long end);
@Specialization
Object sliceArray(Array self, long start, long end) {
return Array.slice(self, start, end, self.length());
}
@Specialization
Object sliceVector(
Vector self,
long start,
long end,
@Shared("interop") @CachedLibrary(limit = "3") InteropLibrary iop) {
try {
return Array.slice(self, start, end, self.length(iop));
} catch (UnsupportedMessageException ex) {
CompilerDirectives.transferToInterpreter();
throw unsupportedMessageException(self);
}
}
@Specialization(replaces = {"sliceArray", "sliceVector"})
Object sliceArrayLike(
Object self,
long start,
long end,
@Shared("interop") @CachedLibrary(limit = "3") InteropLibrary iop) {
try {
long len = iop.getArraySize(self);
return Array.slice(self, start, end, len);
} catch (UnsupportedMessageException ex) {
CompilerDirectives.transferToInterpreter();
throw unsupportedMessageException(self);
}
}
private PanicException unsupportedMessageException(Object self) throws PanicException {
var ctx = EnsoContext.get(this);
var arrayType = ctx.getBuiltins().array();
throw new PanicException(
ctx.getBuiltins().error().makeTypeError(arrayType, self, "self"), this);
Object execute(Object self, long start, long end) {
var len = lengthNode.executeLength(self);
return ArrayLikeHelpers.slice(self, start, end, len);
}
}

View File

@ -11,7 +11,7 @@ import com.oracle.truffle.api.profiles.BranchProfile;
import org.enso.interpreter.Constants;
import org.enso.interpreter.dsl.BuiltinMethod;
import org.enso.interpreter.node.expression.builtin.interop.syntax.HostValueToEnsoNode;
import org.enso.interpreter.node.expression.builtin.mutable.CoerceArrayNode;
import org.enso.interpreter.runtime.data.vector.ArrayLikeCoerceToArrayNode;
import org.enso.interpreter.runtime.error.PanicException;
@BuiltinMethod(
@ -32,7 +32,8 @@ public abstract class ExecuteNode extends Node {
abstract Object execute(Object callable, Object arguments);
@Specialization
Object doExecute(Object callable, Object arguments, @Cached("build()") CoerceArrayNode coerce) {
Object doExecute(
Object callable, Object arguments, @Cached("build()") ArrayLikeCoerceToArrayNode coerce) {
try {
return hostValueToEnsoNode.execute(library.execute(callable, coerce.execute(arguments)));
} catch (UnsupportedMessageException | ArityException | UnsupportedTypeException e) {

View File

@ -5,7 +5,7 @@ import com.oracle.truffle.api.interop.UnsupportedMessageException;
import com.oracle.truffle.api.nodes.Node;
import org.enso.interpreter.Constants;
import org.enso.interpreter.dsl.BuiltinMethod;
import org.enso.interpreter.runtime.data.Array;
import org.enso.interpreter.runtime.data.vector.ArrayLikeHelpers;
@BuiltinMethod(
type = "Polyglot",
@ -20,7 +20,7 @@ public class GetMembersNode extends Node {
try {
return library.getMembers(object);
} catch (UnsupportedMessageException e) {
return Array.empty();
return ArrayLikeHelpers.empty();
}
}
}

View File

@ -11,7 +11,7 @@ import com.oracle.truffle.api.profiles.BranchProfile;
import org.enso.interpreter.Constants;
import org.enso.interpreter.dsl.BuiltinMethod;
import org.enso.interpreter.node.expression.builtin.interop.syntax.HostValueToEnsoNode;
import org.enso.interpreter.node.expression.builtin.mutable.CoerceArrayNode;
import org.enso.interpreter.runtime.data.vector.ArrayLikeCoerceToArrayNode;
import org.enso.interpreter.runtime.error.PanicException;
@BuiltinMethod(
@ -33,7 +33,7 @@ public abstract class InstantiateNode extends Node {
@Specialization
Object doExecute(
Object constructor, Object arguments, @Cached("build()") CoerceArrayNode coerce) {
Object constructor, Object arguments, @Cached("build()") ArrayLikeCoerceToArrayNode coerce) {
try {
var value = library.instantiate(constructor, coerce.execute(arguments));
return fromHost.execute(value);

View File

@ -11,8 +11,8 @@ import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.profiles.BranchProfile;
import org.enso.interpreter.Constants;
import org.enso.interpreter.dsl.BuiltinMethod;
import org.enso.interpreter.node.expression.builtin.mutable.CoerceArrayNode;
import org.enso.interpreter.node.expression.builtin.text.util.ExpectStringNode;
import org.enso.interpreter.runtime.data.vector.ArrayLikeCoerceToArrayNode;
import org.enso.interpreter.runtime.error.PanicException;
@BuiltinMethod(
@ -34,7 +34,10 @@ public abstract class InvokeNode extends Node {
@Specialization
Object doExecute(
Object target, Object name, Object arguments, @Cached("build()") CoerceArrayNode coerce) {
Object target,
Object name,
Object arguments,
@Cached("build()") ArrayLikeCoerceToArrayNode coerce) {
try {
return library.invokeMember(
target, expectStringNode.execute(name), coerce.execute(arguments));

View File

@ -11,7 +11,8 @@ import org.enso.interpreter.runtime.callable.atom.Atom;
import org.enso.interpreter.runtime.callable.atom.StructsLibrary;
import org.enso.interpreter.runtime.callable.function.Function;
import org.enso.interpreter.runtime.callable.function.FunctionSchema;
import org.enso.interpreter.runtime.data.Array;
import org.enso.interpreter.runtime.data.EnsoObject;
import org.enso.interpreter.runtime.data.vector.ArrayLikeHelpers;
import org.enso.interpreter.runtime.error.PanicException;
import org.enso.interpreter.runtime.state.State;
@ -76,7 +77,7 @@ public abstract class AtomWithAHoleNode extends Node {
}
@ExportLibrary(InteropLibrary.class)
static final class HoleInAtom implements TruffleObject {
static final class HoleInAtom implements EnsoObject {
Atom result;
int index;
Function function;
@ -109,7 +110,7 @@ public abstract class AtomWithAHoleNode extends Node {
}
@ExportMessage Object getMembers(boolean includeInternal) {
return new Array("value", "fill");
return ArrayLikeHelpers.wrapStrings("value", "fill");
}
@ExportMessage

View File

@ -6,7 +6,8 @@ import com.oracle.truffle.api.nodes.Node;
import org.enso.interpreter.dsl.BuiltinMethod;
import org.enso.interpreter.runtime.callable.atom.Atom;
import org.enso.interpreter.runtime.callable.atom.StructsLibrary;
import org.enso.interpreter.runtime.data.Array;
import org.enso.interpreter.runtime.data.EnsoObject;
import org.enso.interpreter.runtime.data.vector.ArrayLikeHelpers;
@BuiltinMethod(
type = "Meta",
@ -18,10 +19,10 @@ public abstract class GetAtomFieldsNode extends Node {
return GetAtomFieldsNodeGen.create();
}
abstract Array execute(Atom atom);
abstract EnsoObject execute(Atom atom);
@Specialization
Array doStruct(Atom atom, @CachedLibrary(limit = "2") StructsLibrary structs) {
return new Array(structs.getFields(atom));
EnsoObject doStruct(Atom atom, @CachedLibrary(limit = "2") StructsLibrary structs) {
return ArrayLikeHelpers.wrapObjectsWithCheckAt(structs.getFields(atom));
}
}

View File

@ -6,8 +6,9 @@ import com.oracle.truffle.api.nodes.Node;
import org.enso.interpreter.dsl.BuiltinMethod;
import org.enso.interpreter.runtime.callable.argument.ArgumentDefinition;
import org.enso.interpreter.runtime.callable.atom.AtomConstructor;
import org.enso.interpreter.runtime.data.Array;
import org.enso.interpreter.runtime.data.EnsoObject;
import org.enso.interpreter.runtime.data.text.Text;
import org.enso.interpreter.runtime.data.vector.ArrayLikeHelpers;
@BuiltinMethod(
type = "Meta",
@ -19,20 +20,20 @@ public abstract class GetConstructorFieldNamesNode extends Node {
return GetConstructorFieldNamesNodeGen.create();
}
abstract Array execute(Object obj);
abstract EnsoObject execute(Object obj);
@Specialization
final Array fieldNamesForAtomCtor(AtomConstructor atomConstructor) {
final EnsoObject fieldNamesForAtomCtor(AtomConstructor atomConstructor) {
ArgumentDefinition[] fields = atomConstructor.getFields();
Object[] result = new Object[fields.length];
Text[] result = new Text[fields.length];
for (int i = 0; i < fields.length; i++) {
result[i] = Text.create(fields[i].getName());
}
return new Array(result);
return ArrayLikeHelpers.wrapEnsoObjects(result);
}
@Fallback
final Array fieldNamesForAny(Object any) {
return Array.empty();
final EnsoObject fieldNamesForAny(Object any) {
return ArrayLikeHelpers.empty();
}
}

View File

@ -8,8 +8,9 @@ import org.enso.interpreter.dsl.BuiltinMethod;
import org.enso.interpreter.runtime.EnsoContext;
import org.enso.interpreter.runtime.callable.atom.Atom;
import org.enso.interpreter.runtime.callable.atom.AtomConstructor;
import org.enso.interpreter.runtime.data.Array;
import org.enso.interpreter.runtime.data.EnsoObject;
import org.enso.interpreter.runtime.data.Type;
import org.enso.interpreter.runtime.data.vector.ArrayLikeHelpers;
import org.enso.interpreter.runtime.error.PanicException;
import org.enso.interpreter.runtime.type.TypesGen;
@ -23,24 +24,24 @@ public abstract class GetTypeConstructorsNode extends Node {
return GetTypeConstructorsNodeGen.create();
}
abstract Array execute(Object type, Object factory);
abstract EnsoObject execute(Object type, Object factory);
@Specialization
@CompilerDirectives.TruffleBoundary
Array allConstructors(Type type, AtomConstructor factory) {
EnsoObject allConstructors(Type type, AtomConstructor factory) {
var rawConstructors = type.getConstructors().values();
var rawResult = new Object[rawConstructors.size()];
var rawResult = new EnsoObject[rawConstructors.size()];
int at = 0;
for (var cons : rawConstructors) {
var metaCons = factory.newInstance(cons);
rawResult[at++] = metaCons;
}
return new Array(rawResult);
return ArrayLikeHelpers.wrapEnsoObjects(rawResult);
}
@Fallback
@CompilerDirectives.TruffleBoundary
Array empty(Object type, Object factory) {
EnsoObject empty(Object type, Object factory) {
var ctx = EnsoContext.get(this);
var builtins = ctx.getBuiltins();
Atom payload;

View File

@ -7,8 +7,9 @@ import com.oracle.truffle.api.nodes.Node;
import org.enso.interpreter.dsl.BuiltinMethod;
import org.enso.interpreter.runtime.EnsoContext;
import org.enso.interpreter.runtime.callable.atom.Atom;
import org.enso.interpreter.runtime.data.Array;
import org.enso.interpreter.runtime.data.EnsoObject;
import org.enso.interpreter.runtime.data.Type;
import org.enso.interpreter.runtime.data.vector.ArrayLikeHelpers;
import org.enso.interpreter.runtime.error.PanicException;
@BuiltinMethod(
@ -21,18 +22,20 @@ public abstract class GetTypeMethodsNode extends Node {
return GetTypeMethodsNodeGen.create();
}
abstract Array execute(Object type);
abstract EnsoObject execute(Object type);
@Specialization
@CompilerDirectives.TruffleBoundary
Array allMethods(Type type) {
EnsoObject allMethods(Type type) {
var methods = type.getDefinitionScope().getMethods().get(type);
return methods == null ? Array.empty() : new Array(methods.keySet().toArray());
return methods == null
? ArrayLikeHelpers.empty()
: ArrayLikeHelpers.wrapStrings(methods.keySet().toArray(new String[0]));
}
@Fallback
@CompilerDirectives.TruffleBoundary
Array empty(Object type) {
EnsoObject empty(Object type) {
var ctx = EnsoContext.get(this);
var builtins = ctx.getBuiltins();
Atom payload = builtins.error().makeTypeError("Type", type, "type");

View File

@ -4,9 +4,9 @@ import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.nodes.Node;
import org.enso.interpreter.dsl.BuiltinMethod;
import org.enso.interpreter.node.expression.builtin.mutable.CoerceArrayNode;
import org.enso.interpreter.runtime.callable.atom.Atom;
import org.enso.interpreter.runtime.callable.atom.AtomConstructor;
import org.enso.interpreter.runtime.data.vector.ArrayLikeCoerceToArrayNode;
@BuiltinMethod(
type = "Meta",
@ -22,7 +22,8 @@ public abstract class NewAtomInstanceNode extends Node {
abstract Atom execute(AtomConstructor constructor, Object fields);
@Specialization
Atom doExecute(AtomConstructor constructor, Object fields, @Cached CoerceArrayNode coerce) {
Atom doExecute(
AtomConstructor constructor, Object fields, @Cached ArrayLikeCoerceToArrayNode coerce) {
return constructor.newInstance(coerce.execute(fields));
}
}

View File

@ -1,38 +0,0 @@
package org.enso.interpreter.node.expression.builtin.mutable;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.interop.InteropLibrary;
import com.oracle.truffle.api.interop.InvalidArrayIndexException;
import com.oracle.truffle.api.interop.UnsupportedMessageException;
import com.oracle.truffle.api.nodes.Node;
import org.enso.interpreter.dsl.BuiltinMethod;
import org.enso.interpreter.node.expression.builtin.interop.syntax.HostValueToEnsoNode;
import org.enso.interpreter.runtime.EnsoContext;
import org.enso.interpreter.runtime.error.DataflowError;
@BuiltinMethod(type = "Array", name = "at", description = "Get element of a polyglot array")
public class ArrayAtNode extends Node {
@Child InteropLibrary iop = InteropLibrary.getFactory().createDispatched(3);
@Child HostValueToEnsoNode convert = HostValueToEnsoNode.build();
Object execute(Object self, long index) {
try {
return readElement(self, index);
} catch (UnsupportedMessageException ex) {
CompilerDirectives.transferToInterpreter();
throw new IllegalStateException(ex);
}
}
private Object readElement(Object self, long index) throws UnsupportedMessageException {
try {
long actualIndex = index < 0 ? index + iop.getArraySize(self) : index;
var element = iop.readArrayElement(self, actualIndex);
return convert.execute(element);
} catch (InvalidArrayIndexException e) {
EnsoContext ctx = EnsoContext.get(this);
return DataflowError.withoutTrace(
ctx.getBuiltins().error().makeIndexOutOfBounds(index, iop.getArraySize(self)), this);
}
}
}

View File

@ -1,26 +0,0 @@
package org.enso.interpreter.node.expression.builtin.mutable;
import com.oracle.truffle.api.interop.InteropLibrary;
import com.oracle.truffle.api.interop.UnsupportedMessageException;
import com.oracle.truffle.api.nodes.Node;
import org.enso.interpreter.dsl.BuiltinMethod;
import org.enso.interpreter.runtime.EnsoContext;
import org.enso.interpreter.runtime.error.PanicException;
@BuiltinMethod(type = "Array", name = "length", description = "Length of polyglot array")
public class ArrayLengthNode extends Node {
@Child InteropLibrary iop = InteropLibrary.getFactory().createDispatched(3);
long execute(Object self) {
try {
return iop.getArraySize(self);
} catch (UnsupportedMessageException ex) {
var ctx = EnsoContext.get(this);
var pay =
ctx.getBuiltins()
.error()
.makeUnsupportedArgumentsError(new Object[] {self}, ex.getMessage());
throw new PanicException(pay, this);
}
}
}

View File

@ -11,6 +11,7 @@ import com.oracle.truffle.api.interop.InvalidArrayIndexException;
import com.oracle.truffle.api.interop.UnsupportedMessageException;
import com.oracle.truffle.api.library.CachedLibrary;
import com.oracle.truffle.api.nodes.Node;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
@ -20,6 +21,7 @@ import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.stream.Collectors;
import org.enso.interpreter.dsl.AcceptsError;
import org.enso.interpreter.dsl.BuiltinMethod;
import org.enso.interpreter.node.callable.dispatch.CallOptimiserNode;
@ -32,11 +34,9 @@ import org.enso.interpreter.runtime.EnsoContext;
import org.enso.interpreter.runtime.callable.UnresolvedSymbol;
import org.enso.interpreter.runtime.callable.atom.Atom;
import org.enso.interpreter.runtime.callable.function.Function;
import org.enso.interpreter.runtime.data.Array;
import org.enso.interpreter.runtime.data.ArrayRope;
import org.enso.interpreter.runtime.data.Type;
import org.enso.interpreter.runtime.data.Vector;
import org.enso.interpreter.runtime.data.text.Text;
import org.enso.interpreter.runtime.data.vector.ArrayLikeHelpers;
import org.enso.interpreter.runtime.error.DataflowError;
import org.enso.interpreter.runtime.error.PanicException;
import org.enso.interpreter.runtime.error.Warning;
@ -248,7 +248,7 @@ public abstract class SortVectorNode extends Node {
}
resultVec.addAll(group.elems);
}
var sortedVector = Vector.fromArray(new Array(resultVec.toArray()));
var sortedVector = ArrayLikeHelpers.asVectorWithCheckAt(resultVec.toArray());
// Attach gathered warnings along with different comparators warning
switch (problemBehavior) {
case REPORT_ERROR -> {
@ -290,7 +290,7 @@ public abstract class SortVectorNode extends Node {
private Object sortPrimitiveVector(Object[] elems, DefaultSortComparator javaComparator)
throws CompareException {
Arrays.sort(elems, javaComparator);
var sortedVector = Vector.fromArray(new Array(elems));
var sortedVector = ArrayLikeHelpers.asVectorWithCheckAt(elems);
if (javaComparator.hasWarnings()) {
return attachWarnings(sortedVector, javaComparator.getEncounteredWarnings());

View File

@ -5,7 +5,8 @@ import com.oracle.truffle.api.TruffleStackTrace;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.Node;
import org.enso.interpreter.dsl.BuiltinMethod;
import org.enso.interpreter.runtime.data.Array;
import org.enso.interpreter.runtime.data.EnsoObject;
import org.enso.interpreter.runtime.data.vector.ArrayLikeHelpers;
import org.enso.interpreter.runtime.error.PanicException;
@BuiltinMethod(
@ -14,17 +15,17 @@ import org.enso.interpreter.runtime.error.PanicException;
description = "Gets the current execution stacktrace.",
autoRegister = false)
public class GetStackTraceNode extends Node {
Array execute(VirtualFrame requestOwnStackFrame) {
EnsoObject execute(VirtualFrame requestOwnStackFrame) {
var exception = new PanicException("Stacktrace", this);
TruffleStackTrace.fillIn(exception);
return stackTraceToArray(exception);
}
@CompilerDirectives.TruffleBoundary
public static Array stackTraceToArray(Throwable exception) {
public static EnsoObject stackTraceToArray(Throwable exception) {
var elements = TruffleStackTrace.getStackTrace(exception);
if (elements == null) {
return Array.empty();
return ArrayLikeHelpers.empty();
}
int count = 0;
for (int i = 0; i < elements.size(); i++) {
@ -42,6 +43,6 @@ public class GetStackTraceNode extends Node {
}
arr[at++] = element.getGuestObject();
}
return new Array(arr);
return ArrayLikeHelpers.wrapObjectsWithCheckAt(arr);
}
}

View File

@ -1,5 +1,11 @@
package org.enso.interpreter.node.expression.builtin.text.util;
import org.enso.interpreter.node.expression.builtin.meta.TypeOfNode;
import org.enso.interpreter.runtime.callable.atom.Atom;
import org.enso.interpreter.runtime.callable.atom.AtomConstructor;
import org.enso.interpreter.runtime.data.Type;
import org.enso.interpreter.runtime.type.TypesGen;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.dsl.GenerateUncached;
import com.oracle.truffle.api.dsl.Specialization;
@ -7,11 +13,6 @@ 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;
import org.enso.interpreter.node.expression.builtin.meta.TypeOfNode;
import org.enso.interpreter.runtime.callable.atom.Atom;
import org.enso.interpreter.runtime.callable.atom.AtomConstructor;
import org.enso.interpreter.runtime.data.Type;
import org.enso.interpreter.runtime.type.TypesGen;
@GenerateUncached
public abstract class TypeToDisplayTextNode extends Node {
@ -62,7 +63,7 @@ public abstract class TypeToDisplayTextNode extends Node {
return TypesGen.asUnresolvedSymbol(value).getName() + " (Unresolved_Symbol)";
} else if (TypesGen.isManagedResource(value)) {
return "Managed_Resource";
} else if (TypesGen.isArray(value)) {
} else if (objects.hasArrayElements(value)) {
return "Array";
} else if (TypesGen.isRef(value)) {
return "Ref";

View File

@ -7,7 +7,6 @@ import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.interop.ArityException;
import com.oracle.truffle.api.interop.InteropLibrary;
import com.oracle.truffle.api.interop.TruffleObject;
import com.oracle.truffle.api.interop.UnknownIdentifierException;
import com.oracle.truffle.api.interop.UnsupportedTypeException;
import com.oracle.truffle.api.library.ExportLibrary;
@ -32,9 +31,10 @@ import org.enso.interpreter.runtime.builtin.BuiltinFunction;
import org.enso.interpreter.runtime.builtin.Builtins;
import org.enso.interpreter.runtime.callable.CallerInfo;
import org.enso.interpreter.runtime.callable.function.Function;
import org.enso.interpreter.runtime.data.Array;
import org.enso.interpreter.runtime.data.EnsoObject;
import org.enso.interpreter.runtime.data.Type;
import org.enso.interpreter.runtime.data.text.Text;
import org.enso.interpreter.runtime.data.vector.ArrayLikeHelpers;
import org.enso.interpreter.runtime.scope.LocalScope;
import org.enso.interpreter.runtime.scope.ModuleScope;
import org.enso.interpreter.runtime.type.Types;
@ -48,7 +48,7 @@ import scala.Function1;
/** Represents a source module with a known location. */
@ExportLibrary(InteropLibrary.class)
public final class Module implements TruffleObject {
public final class Module implements EnsoObject {
private ModuleScope scope;
private ModuleSources sources;
private PatchedModuleValues patchedValues;
@ -604,8 +604,8 @@ public final class Module implements TruffleObject {
@CompilerDirectives.TruffleBoundary
private static Object gatherImportStatements(Module module, EnsoContext context) {
Object[] imports = context.getCompiler().gatherImportStatements(module);
return new Array(imports);
String[] imports = context.getCompiler().gatherImportStatements(module);
return ArrayLikeHelpers.wrapStrings(imports);
}
@CompilerDirectives.TruffleBoundary
@ -684,7 +684,7 @@ public final class Module implements TruffleObject {
*/
@ExportMessage
Object getMembers(boolean includeInternal) {
return new Array(
return ArrayLikeHelpers.wrapStrings(
MethodNames.Module.GET_METHOD,
MethodNames.Module.REPARSE,
MethodNames.Module.SET_SOURCE,

View File

@ -31,9 +31,9 @@ import org.enso.interpreter.runtime.EnsoContext;
import org.enso.interpreter.runtime.callable.UnresolvedConversion;
import org.enso.interpreter.runtime.callable.UnresolvedSymbol;
import org.enso.interpreter.runtime.callable.atom.Atom;
import org.enso.interpreter.runtime.data.Array;
import org.enso.interpreter.runtime.data.Type;
import org.enso.interpreter.runtime.data.text.Text;
import org.enso.interpreter.runtime.data.vector.ArrayLikeHelpers;
/** Container for builtin Error types */
public final class Error {
@ -234,7 +234,8 @@ public final class Error {
* given method call
*/
public Atom makeUnsupportedArgumentsError(Object[] args, String message) {
return unsupportedArgumentsError.newInstance(new Array(args), message);
return unsupportedArgumentsError.newInstance(
ArrayLikeHelpers.wrapObjectsWithCheckAt(args), message);
}
/**

View File

@ -11,12 +11,13 @@ import org.enso.interpreter.Constants;
import org.enso.interpreter.node.callable.InteropConversionCallNode;
import org.enso.interpreter.runtime.EnsoContext;
import org.enso.interpreter.runtime.callable.function.Function;
import org.enso.interpreter.runtime.data.EnsoObject;
import org.enso.interpreter.runtime.data.Type;
import org.enso.interpreter.runtime.scope.ModuleScope;
/** Simple runtime value representing a yet-unresolved by-name symbol. */
@ExportLibrary(InteropLibrary.class)
public final class UnresolvedConversion implements TruffleObject {
public final class UnresolvedConversion implements EnsoObject {
private final ModuleScope scope;
/**

View File

@ -4,7 +4,8 @@ import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.ImportStatic;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.interop.*;
import com.oracle.truffle.api.interop.ArityException;
import com.oracle.truffle.api.interop.InteropLibrary;
import com.oracle.truffle.api.library.CachedLibrary;
import com.oracle.truffle.api.library.ExportLibrary;
import com.oracle.truffle.api.library.ExportMessage;
@ -12,12 +13,13 @@ import org.enso.interpreter.Constants;
import org.enso.interpreter.node.callable.InteropMethodCallNode;
import org.enso.interpreter.runtime.EnsoContext;
import org.enso.interpreter.runtime.callable.function.Function;
import org.enso.interpreter.runtime.data.EnsoObject;
import org.enso.interpreter.runtime.data.Type;
import org.enso.interpreter.runtime.scope.ModuleScope;
/** Simple runtime value representing a yet-unresolved by-name symbol. */
@ExportLibrary(InteropLibrary.class)
public final class UnresolvedSymbol implements TruffleObject {
public final class UnresolvedSymbol implements EnsoObject {
private final String name;
private final ModuleScope scope;

View File

@ -8,9 +8,10 @@ import java.util.Set;
import org.enso.interpreter.EnsoLanguage;
import org.enso.interpreter.runtime.callable.UnresolvedSymbol;
import org.enso.interpreter.runtime.callable.function.Function;
import org.enso.interpreter.runtime.data.Array;
import org.enso.interpreter.runtime.data.EnsoObject;
import org.enso.interpreter.runtime.data.Type;
import org.enso.interpreter.runtime.data.text.Text;
import org.enso.interpreter.runtime.data.vector.ArrayLikeHelpers;
import org.enso.interpreter.runtime.error.PanicException;
import org.enso.interpreter.runtime.error.WarningsLibrary;
import org.enso.interpreter.runtime.library.dispatch.TypesLibrary;
@ -22,7 +23,6 @@ import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.exception.AbstractTruffleException;
import com.oracle.truffle.api.interop.ArityException;
import com.oracle.truffle.api.interop.InteropLibrary;
import com.oracle.truffle.api.interop.TruffleObject;
import com.oracle.truffle.api.interop.UnknownIdentifierException;
import com.oracle.truffle.api.interop.UnsupportedMessageException;
import com.oracle.truffle.api.interop.UnsupportedTypeException;
@ -37,7 +37,7 @@ import com.oracle.truffle.api.profiles.BranchProfile;
*/
@ExportLibrary(InteropLibrary.class)
@ExportLibrary(TypesLibrary.class)
public abstract class Atom implements TruffleObject {
public abstract class Atom implements EnsoObject {
final AtomConstructor constructor;
private Integer hashCode;
@ -140,7 +140,7 @@ public abstract class Atom implements TruffleObject {
@ExportMessage
@CompilerDirectives.TruffleBoundary
public Array getMembers(boolean includeInternal) {
public EnsoObject getMembers(boolean includeInternal) {
Map<String, Function> members = constructor.getDefinitionScope().getMethods().get(constructor.getType());
Set<String> allMembers = new HashSet<>();
if (members != null) {
@ -150,8 +150,8 @@ public abstract class Atom implements TruffleObject {
if (members != null) {
allMembers.addAll(members.keySet());
}
Object[] mems = allMembers.toArray();
return new Array(mems);
String[] mems = allMembers.toArray(new String[0]);
return ArrayLikeHelpers.wrapStrings(mems);
}
@ExportMessage

View File

@ -6,7 +6,6 @@ import com.oracle.truffle.api.RootCallTarget;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.interop.ArityException;
import com.oracle.truffle.api.interop.InteropLibrary;
import com.oracle.truffle.api.interop.TruffleObject;
import com.oracle.truffle.api.library.CachedLibrary;
import com.oracle.truffle.api.library.ExportLibrary;
import com.oracle.truffle.api.library.ExportMessage;
@ -27,6 +26,7 @@ import org.enso.interpreter.runtime.callable.argument.ArgumentDefinition;
import org.enso.interpreter.runtime.callable.atom.unboxing.Layout;
import org.enso.interpreter.runtime.callable.function.Function;
import org.enso.interpreter.runtime.callable.function.FunctionSchema;
import org.enso.interpreter.runtime.data.EnsoObject;
import org.enso.interpreter.runtime.data.Type;
import org.enso.interpreter.runtime.library.dispatch.TypesLibrary;
import org.enso.interpreter.runtime.scope.LocalScope;
@ -36,7 +36,7 @@ import org.enso.pkg.QualifiedName;
/** A representation of an Atom constructor. */
@ExportLibrary(InteropLibrary.class)
@ExportLibrary(TypesLibrary.class)
public final class AtomConstructor implements TruffleObject {
public final class AtomConstructor implements EnsoObject {
private final String name;
private final ModuleScope definitionScope;
@ -51,12 +51,13 @@ public final class AtomConstructor implements TruffleObject {
private final Type type;
/**
* Creates a new Atom constructor for a given name. The constructor is not valid until {@link
* Creates a new Atom constructor for a given name.The constructor is not valid until {@link
* AtomConstructor#initializeFields(EnsoLanguage, LocalScope, ExpressionNode[], ExpressionNode[],
* Annotation[], ArgumentDefinition...)} is called.
* Annotation[], ArgumentDefinition[])} is called.
*
* @param name the name of the Atom constructor
* @param definitionScope the scope in which this constructor was defined
* @param type
*/
public AtomConstructor(String name, ModuleScope definitionScope, Type type) {
this(name, definitionScope, type, false);

View File

@ -1,14 +1,15 @@
package org.enso.interpreter.runtime.callable.atom.unboxing;
import com.oracle.truffle.api.exception.AbstractTruffleException;
import com.oracle.truffle.api.interop.TruffleObject;
import com.oracle.truffle.api.nodes.Node;
import org.enso.interpreter.node.callable.InvokeCallableNode;
import org.enso.interpreter.node.callable.dispatch.InvokeFunctionNode;
import org.enso.interpreter.runtime.EnsoContext;
import org.enso.interpreter.runtime.callable.argument.CallArgumentInfo;
import org.enso.interpreter.runtime.callable.atom.Atom;
import org.enso.interpreter.runtime.callable.function.Function;
import org.enso.interpreter.runtime.data.EnsoObject;
import org.enso.interpreter.runtime.state.State;
/**
@ -55,7 +56,7 @@ final class SuspendedFieldGetterNode extends UnboxingAtom.FieldGetterNode {
}
}
private static final class SuspendedException implements TruffleObject {
private static final class SuspendedException implements EnsoObject {
final AbstractTruffleException ex;
SuspendedException(AbstractTruffleException ex) {

View File

@ -9,7 +9,6 @@ import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.MaterializedFrame;
import com.oracle.truffle.api.interop.ArityException;
import com.oracle.truffle.api.interop.InteropLibrary;
import com.oracle.truffle.api.interop.TruffleObject;
import com.oracle.truffle.api.interop.UnknownIdentifierException;
import com.oracle.truffle.api.interop.UnsupportedTypeException;
import com.oracle.truffle.api.library.CachedLibrary;
@ -24,8 +23,9 @@ import org.enso.interpreter.runtime.EnsoContext;
import org.enso.interpreter.runtime.callable.Annotation;
import org.enso.interpreter.runtime.callable.CallerInfo;
import org.enso.interpreter.runtime.callable.argument.ArgumentDefinition;
import org.enso.interpreter.runtime.data.Array;
import org.enso.interpreter.runtime.data.EnsoObject;
import org.enso.interpreter.runtime.data.Type;
import org.enso.interpreter.runtime.data.vector.ArrayLikeHelpers;
import org.enso.interpreter.runtime.library.dispatch.TypesLibrary;
import org.enso.interpreter.runtime.state.State;
import org.enso.interpreter.runtime.type.Types;
@ -34,7 +34,7 @@ import org.enso.polyglot.MethodNames;
/** A runtime representation of a function object in Enso. */
@ExportLibrary(InteropLibrary.class)
@ExportLibrary(TypesLibrary.class)
public final class Function implements TruffleObject {
public final class Function implements EnsoObject {
private final RootCallTarget callTarget;
private final MaterializedFrame scope;
private final FunctionSchema schema;
@ -268,7 +268,7 @@ public final class Function implements TruffleObject {
*/
@ExportMessage
Object getMembers(boolean includeInternal) {
return new Array(MethodNames.Function.EQUALS);
return ArrayLikeHelpers.wrapStrings(MethodNames.Function.EQUALS);
}
/**

View File

@ -3,7 +3,6 @@ package org.enso.interpreter.runtime.data;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.interop.InteropLibrary;
import com.oracle.truffle.api.interop.TruffleObject;
import com.oracle.truffle.api.interop.UnsupportedMessageException;
import com.oracle.truffle.api.library.CachedLibrary;
import com.oracle.truffle.api.library.ExportLibrary;
@ -20,7 +19,7 @@ import org.enso.polyglot.common_utils.Core_Date_Utils;
@ExportLibrary(InteropLibrary.class)
@ExportLibrary(TypesLibrary.class)
@Builtin(pkg = "date", name = "Date", stdlibName = "Standard.Base.Data.Time.Date.Date")
public final class EnsoDate implements TruffleObject {
public final class EnsoDate implements EnsoObject {
private final LocalDate date;
public EnsoDate(LocalDate date) {

View File

@ -3,7 +3,6 @@ package org.enso.interpreter.runtime.data;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.interop.InteropLibrary;
import com.oracle.truffle.api.interop.TruffleObject;
import com.oracle.truffle.api.interop.UnsupportedMessageException;
import com.oracle.truffle.api.library.CachedLibrary;
import com.oracle.truffle.api.library.ExportLibrary;
@ -25,7 +24,7 @@ import org.enso.interpreter.runtime.library.dispatch.TypesLibrary;
pkg = "date",
name = "DateTime",
stdlibName = "Standard.Base.Data.Time.Date_Time.Date_Time")
public final class EnsoDateTime implements TruffleObject {
public final class EnsoDateTime implements EnsoObject {
private final ZonedDateTime dateTime;
public EnsoDateTime(ZonedDateTime dateTime) {

View File

@ -3,7 +3,6 @@ package org.enso.interpreter.runtime.data;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.interop.InteropLibrary;
import com.oracle.truffle.api.interop.TruffleObject;
import com.oracle.truffle.api.interop.UnsupportedMessageException;
import com.oracle.truffle.api.library.CachedLibrary;
import com.oracle.truffle.api.library.ExportLibrary;
@ -23,7 +22,7 @@ import org.enso.interpreter.runtime.library.dispatch.TypesLibrary;
@ExportLibrary(InteropLibrary.class)
@ExportLibrary(TypesLibrary.class)
@Builtin(pkg = "date", name = "Duration", stdlibName = "Standard.Base.Data.Time.Duration.Duration")
public final class EnsoDuration implements TruffleObject {
public final class EnsoDuration implements EnsoObject {
private final Duration duration;
public EnsoDuration(Duration duration) {

View File

@ -31,6 +31,8 @@ import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.util.Set;
import org.enso.interpreter.runtime.data.vector.ArrayLikeHelpers;
import com.oracle.truffle.api.dsl.Cached;
/**
@ -40,7 +42,7 @@ import com.oracle.truffle.api.dsl.Cached;
@ExportLibrary(InteropLibrary.class)
@ExportLibrary(TypesLibrary.class)
@Builtin(pkg = "io", name = "File", stdlibName = "Standard.Base.System.File.File")
public final class EnsoFile implements TruffleObject {
public final class EnsoFile implements EnsoObject {
private final TruffleFile truffleFile;
public EnsoFile(TruffleFile truffleFile) {
@ -106,7 +108,7 @@ public final class EnsoFile implements TruffleObject {
@Builtin.Method(name = "read_last_bytes_builtin")
@Builtin.WrapException(from = IOException.class)
@CompilerDirectives.TruffleBoundary
public ArrayOverBuffer readLastBytes(long n) throws IOException {
public EnsoObject readLastBytes(long n) throws IOException {
try (SeekableByteChannel channel =
this.truffleFile.newByteChannel(Set.of(StandardOpenOption.READ))) {
int bytesToRead = Math.toIntExact(Math.min(channel.size(), n));
@ -117,7 +119,7 @@ public final class EnsoFile implements TruffleObject {
}
buffer.flip();
return ArrayOverBuffer.wrapBuffer(buffer);
return ArrayLikeHelpers.wrapBuffer(buffer);
}
}
@ -213,8 +215,8 @@ public final class EnsoFile implements TruffleObject {
@Builtin.Method(name = "list_immediate_children_array")
@Builtin.WrapException(from = IOException.class)
@CompilerDirectives.TruffleBoundary
public EnsoFile[] list() throws IOException {
return this.truffleFile.list().stream().map(EnsoFile::new).toArray(EnsoFile[]::new);
public EnsoObject list() throws IOException {
return ArrayLikeHelpers.wrapEnsoObjects(this.truffleFile.list().stream().map(EnsoFile::new).toArray(EnsoFile[]::new));
}
@Builtin.Method

View File

@ -0,0 +1,6 @@
package org.enso.interpreter.runtime.data;
import com.oracle.truffle.api.interop.TruffleObject;
/** All non-primitive Enso types extends from {@code EnsoObject}. */
public interface EnsoObject extends TruffleObject {}

View File

@ -4,7 +4,6 @@ import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.interop.InteropLibrary;
import com.oracle.truffle.api.interop.TruffleObject;
import com.oracle.truffle.api.interop.UnsupportedMessageException;
import com.oracle.truffle.api.library.CachedLibrary;
import com.oracle.truffle.api.library.ExportLibrary;
@ -24,7 +23,7 @@ import org.enso.interpreter.runtime.library.dispatch.TypesLibrary;
pkg = "date",
name = "TimeOfDay",
stdlibName = "Standard.Base.Data.Time.Time_Of_Day.Time_Of_Day")
public final class EnsoTimeOfDay implements TruffleObject {
public final class EnsoTimeOfDay implements EnsoObject {
private final LocalTime localTime;
public EnsoTimeOfDay(LocalTime localTime) {

View File

@ -3,7 +3,6 @@ package org.enso.interpreter.runtime.data;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.interop.InteropLibrary;
import com.oracle.truffle.api.interop.TruffleObject;
import com.oracle.truffle.api.library.CachedLibrary;
import com.oracle.truffle.api.library.ExportLibrary;
import com.oracle.truffle.api.library.ExportMessage;
@ -22,7 +21,7 @@ import org.enso.interpreter.runtime.library.dispatch.TypesLibrary;
pkg = "date",
name = "TimeZone",
stdlibName = "Standard.Base.Data.Time.Time_Zone.Time_Zone")
public final class EnsoTimeZone implements TruffleObject {
public final class EnsoTimeZone implements EnsoObject {
private final ZoneId zone;
public EnsoTimeZone(ZoneId zone) {

View File

@ -2,7 +2,6 @@ package org.enso.interpreter.runtime.data;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.interop.InteropLibrary;
import com.oracle.truffle.api.interop.TruffleObject;
import com.oracle.truffle.api.library.CachedLibrary;
import com.oracle.truffle.api.library.ExportLibrary;
import com.oracle.truffle.api.library.ExportMessage;
@ -16,7 +15,7 @@ import org.enso.interpreter.runtime.library.dispatch.TypesLibrary;
@ExportLibrary(InteropLibrary.class)
@ExportLibrary(TypesLibrary.class)
@Builtin(pkg = "resource", stdlibName = "Standard.Base.Runtime.Managed_Resource.Managed_Resource")
public final class ManagedResource implements TruffleObject {
public final class ManagedResource implements EnsoObject {
private final Object resource;
private final PhantomReference<ManagedResource> phantomReference;

View File

@ -2,7 +2,6 @@ package org.enso.interpreter.runtime.data;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.interop.InteropLibrary;
import com.oracle.truffle.api.interop.TruffleObject;
import com.oracle.truffle.api.library.CachedLibrary;
import com.oracle.truffle.api.library.ExportLibrary;
import com.oracle.truffle.api.library.ExportMessage;
@ -14,7 +13,7 @@ import org.enso.interpreter.runtime.library.dispatch.TypesLibrary;
@ExportLibrary(InteropLibrary.class)
@ExportLibrary(TypesLibrary.class)
@Builtin(pkg = "mutable", stdlibName = "Standard.Base.Runtime.Ref.Ref")
public final class Ref implements TruffleObject {
public final class Ref implements EnsoObject {
private volatile Object value;
/**

View File

@ -3,7 +3,6 @@ package org.enso.interpreter.runtime.data;
import com.oracle.truffle.api.CompilerAsserts;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.interop.InteropLibrary;
import com.oracle.truffle.api.interop.TruffleObject;
import com.oracle.truffle.api.interop.UnknownIdentifierException;
import com.oracle.truffle.api.interop.UnsupportedMessageException;
import com.oracle.truffle.api.library.CachedLibrary;
@ -27,13 +26,14 @@ import org.enso.interpreter.runtime.callable.argument.ArgumentDefinition;
import org.enso.interpreter.runtime.callable.atom.AtomConstructor;
import org.enso.interpreter.runtime.callable.function.Function;
import org.enso.interpreter.runtime.callable.function.FunctionSchema;
import org.enso.interpreter.runtime.data.vector.ArrayLikeHelpers;
import org.enso.interpreter.runtime.library.dispatch.TypesLibrary;
import org.enso.interpreter.runtime.scope.ModuleScope;
import org.enso.pkg.QualifiedName;
@ExportLibrary(TypesLibrary.class)
@ExportLibrary(InteropLibrary.class)
public final class Type implements TruffleObject {
public final class Type implements EnsoObject {
private final String name;
private @CompilerDirectives.CompilationFinal ModuleScope definitionScope;
private final boolean builtin;
@ -220,7 +220,7 @@ public final class Type implements TruffleObject {
throw UnsupportedMessageException.create();
}
assert getSupertype() != null;
return new Array(getSupertype());
return ArrayLikeHelpers.wrapEnsoObjects(getSupertype());
}
@ExportMessage
@ -286,8 +286,8 @@ public final class Type implements TruffleObject {
@ExportMessage
@CompilerDirectives.TruffleBoundary
Array getMembers(boolean includeInternal) {
return new Array(constructors.keySet().toArray(Object[]::new));
EnsoObject getMembers(boolean includeInternal) {
return ArrayLikeHelpers.wrapStrings(constructors.keySet().toArray(String[]::new));
}
@ExportMessage

View File

@ -1,240 +0,0 @@
package org.enso.interpreter.runtime.data;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.Cached.Shared;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.interop.InteropLibrary;
import com.oracle.truffle.api.interop.InvalidArrayIndexException;
import com.oracle.truffle.api.interop.TruffleObject;
import com.oracle.truffle.api.interop.UnsupportedMessageException;
import com.oracle.truffle.api.interop.UnsupportedTypeException;
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 org.enso.interpreter.dsl.Builtin;
import org.enso.interpreter.node.callable.dispatch.InvokeFunctionNode;
import org.enso.interpreter.node.expression.builtin.interop.syntax.HostValueToEnsoNode;
import org.enso.interpreter.runtime.EnsoContext;
import org.enso.interpreter.runtime.callable.function.Function;
import org.enso.interpreter.runtime.error.DataflowError;
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.enso.interpreter.runtime.state.State;
@ExportLibrary(InteropLibrary.class)
@ExportLibrary(TypesLibrary.class)
@ExportLibrary(WarningsLibrary.class)
@Builtin(pkg = "immutable", stdlibName = "Standard.Base.Data.Vector.Vector")
public final class Vector implements TruffleObject {
private final Object storage;
private Vector(Object storage) {
if (CompilerDirectives.inInterpreter()) {
if (!InteropLibrary.getUncached().hasArrayElements(storage)) {
throw new IllegalStateException("Vector needs array-like delegate, but got: " + storage);
}
}
this.storage = storage;
}
@Builtin.Method(
name = "new",
description = "Creates new Vector with given length and provided elements.",
autoRegister = false)
@Builtin.Specialize()
public static Object newFromFunction(
VirtualFrame frame,
long length,
Function fun,
State state,
@Cached("buildWithArity(1)") InvokeFunctionNode invokeFunctionNode) {
Object[] target = new Object[Math.toIntExact(length)];
for (int i = 0; i < target.length; i++) {
var value = invokeFunctionNode.execute(fun, frame, state, new Long[] {(long) i});
if (value instanceof DataflowError) {
return value;
}
target[i] = value;
}
return new Vector(new Array(target));
}
@Builtin.Method(
name = "to_array",
description = "Returns an Array representation of this Vector.")
public final Object toArray() {
return this.storage;
}
@Builtin.Method(description = "Returns the length of this Vector.")
@Builtin.Specialize
@Builtin.WrapException(from = UnsupportedMessageException.class)
public final long length(InteropLibrary interop) throws UnsupportedMessageException {
return interop.getArraySize(storage);
}
//
// messages for the InteropLibrary
//
/**
* Marks the object as array-like for Polyglot APIs.
*
* @return {@code true}
*/
@ExportMessage
boolean hasArrayElements() {
return true;
}
@ExportMessage
long getArraySize(@Shared("interop") @CachedLibrary(limit = "3") InteropLibrary interop)
throws UnsupportedMessageException {
return interop.getArraySize(storage);
}
/**
* Handles reading an element by index through the polyglot API.
*
* @param index the index to read
* @return the element value at the provided index
* @throws InvalidArrayIndexException when the index is out of bounds.
*/
@ExportMessage
public Object readArrayElement(
long index,
@Shared("interop") @CachedLibrary(limit = "3") InteropLibrary interop,
@CachedLibrary(limit = "3") WarningsLibrary warnings,
@Cached HostValueToEnsoNode toEnso)
throws InvalidArrayIndexException, UnsupportedMessageException {
var v = interop.readArrayElement(this.storage, index);
if (warnings.hasWarnings(this.storage)) {
Warning[] extracted = warnings.getWarnings(this.storage, null);
if (warnings.hasWarnings(v)) {
v = warnings.removeWarnings(v);
}
return WithWarnings.wrap(EnsoContext.get(interop), toEnso.execute(v), extracted);
}
return toEnso.execute(v);
}
public static Vector fromArray(Object arr) {
return new Vector(arr);
}
/**
* Exposes an index validity check through the polyglot API.
*
* @param index the index to check
* @return {@code true} if the index is valid, {@code false} otherwise.
*/
@ExportMessage
boolean isArrayElementReadable(
long index, @Shared("interop") @CachedLibrary(limit = "3") InteropLibrary interop) {
try {
var size = interop.getArraySize(storage);
return index < size && index >= 0;
} catch (UnsupportedMessageException e) {
return false;
}
}
@ExportMessage
boolean isArrayElementModifiable(long index) {
return false;
}
@ExportMessage
final void writeArrayElement(long index, Object value)
throws UnsupportedMessageException, UnsupportedTypeException, InvalidArrayIndexException {
throw UnsupportedMessageException.create();
}
@ExportMessage
boolean isArrayElementInsertable(long index) {
return false;
}
@ExportMessage
boolean isArrayElementRemovable(long index) {
return false;
}
@ExportMessage
final void removeArrayElement(long index) throws UnsupportedMessageException {
throw UnsupportedMessageException.create();
}
@ExportMessage
@CompilerDirectives.TruffleBoundary
String toDisplayString(boolean allowSideEffects) {
final InteropLibrary iop = InteropLibrary.getUncached();
return DisplayArrayUtils.toDisplayString(this, allowSideEffects, iop);
}
@ExportMessage
Type getMetaObject(@CachedLibrary("this") InteropLibrary thisLib) {
return EnsoContext.get(thisLib).getBuiltins().vector();
}
@ExportMessage
boolean hasMetaObject() {
return true;
}
//
// methods for TypesLibrary
//
@ExportMessage
boolean hasType() {
return true;
}
@ExportMessage
Type getType(@CachedLibrary("this") TypesLibrary thisLib, @Cached("1") int ignore) {
return EnsoContext.get(thisLib).getBuiltins().vector();
}
@ExportMessage
boolean hasWarnings(@Shared("warnsLib") @CachedLibrary(limit = "3") WarningsLibrary warnings) {
return warnings.hasWarnings(this.storage);
}
@ExportMessage
Warning[] getWarnings(
Node location, @Shared("warnsLib") @CachedLibrary(limit = "3") WarningsLibrary warnings)
throws UnsupportedMessageException {
return warnings.getWarnings(this.storage, location);
}
@ExportMessage
Vector removeWarnings(@Shared("warnsLib") @CachedLibrary(limit = "3") WarningsLibrary warnings)
throws UnsupportedMessageException {
return new Vector(warnings.removeWarnings(this.storage));
}
@ExportMessage
boolean isLimitReached(@Shared("warnsLib") @CachedLibrary(limit = "3") WarningsLibrary warnings) {
return warnings.isLimitReached(this.storage);
}
//
// helper methods
//
@Override
@CompilerDirectives.TruffleBoundary
public String toString() {
return toDisplayString(false);
}
@SuppressWarnings("unchecked")
private static <E extends Exception> E raise(Class<E> clazz, Throwable t) throws E {
throw (E) t;
}
}

View File

@ -3,7 +3,6 @@ package org.enso.interpreter.runtime.data.hash;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.interop.InteropLibrary;
import com.oracle.truffle.api.interop.TruffleObject;
import com.oracle.truffle.api.interop.UnknownKeyException;
import com.oracle.truffle.api.interop.UnsupportedMessageException;
import com.oracle.truffle.api.library.CachedLibrary;
@ -14,9 +13,10 @@ import org.enso.interpreter.dsl.Builtin;
import org.enso.interpreter.node.expression.builtin.meta.EqualsNode;
import org.enso.interpreter.node.expression.builtin.meta.HashCodeNode;
import org.enso.interpreter.runtime.EnsoContext;
import org.enso.interpreter.runtime.data.EnsoObject;
import org.enso.interpreter.runtime.data.Type;
import org.enso.interpreter.runtime.data.Vector;
import org.enso.interpreter.runtime.data.hash.EnsoHashMapBuilder.StorageEntry;
import org.enso.interpreter.runtime.data.vector.ArrayLikeHelpers;
import org.enso.interpreter.runtime.library.dispatch.TypesLibrary;
/**
@ -32,7 +32,7 @@ import org.enso.interpreter.runtime.library.dispatch.TypesLibrary;
@ExportLibrary(TypesLibrary.class)
@ExportLibrary(InteropLibrary.class)
@Builtin(stdlibName = "Standard.Base.Data.Map.Map", name = "Map")
public final class EnsoHashMap implements TruffleObject {
public final class EnsoHashMap implements EnsoObject {
private final EnsoHashMapBuilder mapBuilder;
/**
* Size of this Map. Basically an index into {@link EnsoHashMapBuilder}'s storage. See {@link
@ -83,7 +83,8 @@ public final class EnsoHashMap implements TruffleObject {
}
}
cachedVectorRepresentation =
Vector.fromArray(HashEntriesVector.createFromKeysAndValues(keys, values));
ArrayLikeHelpers.asVectorFromArray(
HashEntriesVector.createFromKeysAndValues(keys, values));
}
return cachedVectorRepresentation;
}

View File

@ -3,11 +3,11 @@ package org.enso.interpreter.runtime.data.hash;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.interop.InteropLibrary;
import com.oracle.truffle.api.interop.InvalidArrayIndexException;
import com.oracle.truffle.api.interop.TruffleObject;
import com.oracle.truffle.api.interop.UnsupportedMessageException;
import com.oracle.truffle.api.library.ExportLibrary;
import com.oracle.truffle.api.library.ExportMessage;
import org.enso.interpreter.runtime.data.Vector;
import org.enso.interpreter.runtime.data.EnsoObject;
import org.enso.interpreter.runtime.data.vector.ArrayLikeHelpers;
/**
* A vector used to hold hash map entries, where each entry is represented as a 2-element vector.
@ -15,14 +15,14 @@ import org.enso.interpreter.runtime.data.Vector;
* (array), and for Enso {@code Map.to_vector} method. May be empty.
*/
@ExportLibrary(InteropLibrary.class)
final class HashEntriesVector implements TruffleObject {
private final Vector[] entryPairs;
final class HashEntriesVector implements EnsoObject {
private final EnsoObject[] entryPairs;
private HashEntriesVector(Object[] keys, Object[] values) {
assert keys.length == values.length;
this.entryPairs = new Vector[keys.length];
this.entryPairs = new EnsoObject[keys.length];
for (int i = 0; i < keys.length; i++) {
entryPairs[i] = Vector.fromArray(new EntryPair(keys[i], values[i]));
entryPairs[i] = ArrayLikeHelpers.asVectorFromArray(new EntryPair(keys[i], values[i]));
}
}
@ -74,7 +74,7 @@ final class HashEntriesVector implements TruffleObject {
}
@ExportLibrary(InteropLibrary.class)
static final class EntryPair implements TruffleObject {
static final class EntryPair implements EnsoObject {
private final Object key;
private final Object value;

View File

@ -1,5 +1,8 @@
package org.enso.interpreter.runtime.data.hash;
import org.enso.interpreter.dsl.BuiltinMethod;
import org.enso.interpreter.runtime.data.vector.ArrayLikeHelpers;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.Fallback;
import com.oracle.truffle.api.dsl.GenerateUncached;
@ -11,9 +14,6 @@ import com.oracle.truffle.api.interop.UnsupportedMessageException;
import com.oracle.truffle.api.library.CachedLibrary;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.profiles.ConditionProfile;
import org.enso.interpreter.dsl.BuiltinMethod;
import org.enso.interpreter.runtime.data.Vector;
@BuiltinMethod(
type = "Map",
@ -48,7 +48,7 @@ public abstract class HashMapToVectorNode extends Node {
@Fallback
Object fallback(Object object) {
return Vector.fromArray(HashEntriesVector.createEmpty());
return ArrayLikeHelpers.asVectorWithCheckAt(HashEntriesVector.createEmpty());
}
private static Object createEntriesVectorFromForeignMap(
@ -67,7 +67,7 @@ public abstract class HashMapToVectorNode extends Node {
values[arrIdx] = iteratorInterop.readArrayElement(keyValueArr, 1);
arrIdx++;
}
return Vector.fromArray(
return ArrayLikeHelpers.asVectorFromArray(
HashEntriesVector.createFromKeysAndValues(keys, values)
);
} catch (UnsupportedMessageException | StopIterationException | InvalidArrayIndexException e) {

View File

@ -8,6 +8,7 @@ import java.util.concurrent.locks.ReentrantLock;
import org.enso.interpreter.dsl.Builtin;
import org.enso.interpreter.node.expression.builtin.text.util.ToJavaStringNode;
import org.enso.interpreter.runtime.EnsoContext;
import org.enso.interpreter.runtime.data.EnsoObject;
import org.enso.interpreter.runtime.data.Type;
import org.enso.interpreter.runtime.library.dispatch.TypesLibrary;
import org.enso.polyglot.common_utils.Core_Text_Utils;
@ -16,7 +17,6 @@ import com.ibm.icu.text.Normalizer2;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.interop.InteropLibrary;
import com.oracle.truffle.api.interop.TruffleObject;
import com.oracle.truffle.api.library.CachedLibrary;
import com.oracle.truffle.api.library.ExportLibrary;
import com.oracle.truffle.api.library.ExportMessage;
@ -24,7 +24,7 @@ import com.oracle.truffle.api.library.ExportMessage;
/** The main runtime type for Enso's Text. */
@ExportLibrary(InteropLibrary.class)
@ExportLibrary(TypesLibrary.class)
public final class Text implements TruffleObject {
public final class Text implements EnsoObject {
private static final Lock LOCK = new ReentrantLock();
private volatile Object contents;
private volatile int length = -1;

View File

@ -1,11 +1,10 @@
package org.enso.interpreter.runtime.data;
package org.enso.interpreter.runtime.data.vector;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.Cached.Shared;
import com.oracle.truffle.api.interop.InteropLibrary;
import com.oracle.truffle.api.interop.InvalidArrayIndexException;
import com.oracle.truffle.api.interop.TruffleObject;
import com.oracle.truffle.api.interop.UnsupportedMessageException;
import com.oracle.truffle.api.library.CachedLibrary;
import com.oracle.truffle.api.library.ExportLibrary;
@ -15,6 +14,8 @@ import com.oracle.truffle.api.profiles.BranchProfile;
import java.util.Arrays;
import org.enso.interpreter.dsl.Builtin;
import org.enso.interpreter.runtime.EnsoContext;
import org.enso.interpreter.runtime.data.EnsoObject;
import org.enso.interpreter.runtime.data.Type;
import org.enso.interpreter.runtime.error.Warning;
import org.enso.interpreter.runtime.error.WarningsLibrary;
import org.enso.interpreter.runtime.error.WithWarnings;
@ -26,7 +27,7 @@ import org.graalvm.collections.EconomicSet;
@ExportLibrary(TypesLibrary.class)
@ExportLibrary(WarningsLibrary.class)
@Builtin(pkg = "mutable", stdlibName = "Standard.Base.Data.Array.Array")
public final class Array implements TruffleObject {
final class Array implements EnsoObject {
private final Object[] items;
private Boolean withWarnings;
private Warning[] cachedWarnings;
@ -36,22 +37,11 @@ public final class Array implements TruffleObject {
*
* @param items the element values
*/
public Array(Object... items) {
Array(Object... items) {
assert noNulls(items);
this.items = items;
}
/**
* Creates an uninitialized array of the given size. The values must be filled before the array is
* returned to Enso.
*
* @param size the size of the created array.
*/
public static Array allocate(long size) {
var arr = new Object[(int) size];
return new Array(arr);
}
private static boolean noNulls(Object[] arr) {
for (Object o : arr) {
if (o == null) {
@ -62,7 +52,7 @@ public final class Array implements TruffleObject {
}
/** @return the elements of this array as a java array. */
public Object[] getItems() {
final Object[] getItems() {
return items;
}
@ -72,7 +62,7 @@ public final class Array implements TruffleObject {
* @return {@code true}
*/
@ExportMessage
public boolean hasArrayElements() {
boolean hasArrayElements() {
return true;
}
@ -84,7 +74,7 @@ public final class Array implements TruffleObject {
* @throws InvalidArrayIndexException when the index is out of bounds.
*/
@ExportMessage
public Object readArrayElement(
Object readArrayElement(
long index,
@CachedLibrary(limit = "3") WarningsLibrary warnings,
@Cached BranchProfile errProfile,
@ -108,29 +98,10 @@ public final class Array implements TruffleObject {
return v;
}
public long length() {
long length() {
return items.length;
}
/** @return an empty array */
public static Array empty() {
return allocate(0);
}
/**
* 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;
}
/**
* Exposes the size of this collection through the polyglot API.
*

View File

@ -0,0 +1,220 @@
package org.enso.interpreter.runtime.data.vector;
import java.util.Arrays;
import org.enso.interpreter.runtime.data.EnsoObject;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.interop.InteropLibrary;
import com.oracle.truffle.api.interop.InvalidArrayIndexException;
import com.oracle.truffle.api.interop.UnknownIdentifierException;
import com.oracle.truffle.api.interop.UnsupportedMessageException;
import com.oracle.truffle.api.interop.UnsupportedTypeException;
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;
@ExportLibrary(InteropLibrary.class)
final class ArrayBuilder implements EnsoObject {
private static final String[] MEMBERS = new String[] { "isEmpty", "add", "appendTo", "get", "getSize", "toArray" };
private static final Object[] EMPTY_ARRAY = new Object[0];
private final int initialCapacity;
private int size;
private Object primitiveArray;
private Object[] objectArray;
private ArrayBuilder(int initialCapacity) {
this.initialCapacity = Math.max(1, initialCapacity);
}
/**
* Creates new builder
*/
static ArrayBuilder newBuilder(int capacity) {
return new ArrayBuilder(capacity);
}
/**
* Is the builder empty?
*/
boolean isEmpty() {
return size == 0;
}
/**
* Adds an element to the builder
*
* @param e the element to add
*/
void add(Object e) {
if (objectArray != null) {
if (size == objectArray.length) {
CompilerDirectives.transferToInterpreter();
objectArray = Arrays.copyOf(objectArray, size * 2);
}
objectArray[size++] = e;
} else if (primitiveArray instanceof long[] longArray) {
if (e instanceof Long l) {
if (size == longArray.length) {
CompilerDirectives.transferToInterpreter();
primitiveArray = longArray = Arrays.copyOf(longArray, size * 2);
}
longArray[size++] = l;
} else {
CompilerDirectives.transferToInterpreter();
objectArray = new Object[longArray.length];
for (int i = 0; i < size; i++) {
objectArray[i] = longArray[i];
}
primitiveArray = null;
add(e);
}
} else if (primitiveArray instanceof double[] doubleArray) {
if (e instanceof Double d) {
if (size == doubleArray.length) {
CompilerDirectives.transferToInterpreter();
primitiveArray = doubleArray = Arrays.copyOf(doubleArray, size * 2);
}
doubleArray[size++] = d;
} else {
CompilerDirectives.transferToInterpreter();
objectArray = new Object[doubleArray.length];
for (int i = 0; i < size; i++) {
objectArray[i] = doubleArray[i];
}
primitiveArray = null;
add(e);
}
} else {
assert objectArray == null;
assert primitiveArray == null;
assert size == 0;
if (e instanceof Long l) {
var arr = new long[initialCapacity];
arr[0] = l;
primitiveArray = arr;
} else if (e instanceof Double d) {
var arr = new double[initialCapacity];
arr[0] = d;
primitiveArray = arr;
} else {
var arr = new Object[initialCapacity];
arr[0] = e;
objectArray = arr;
}
size = 1;
}
}
/**
* Obtains an element from the builder
*/
private Object get(int index, Node node) {
try {
if (index >= 0 && index < size) {
if (objectArray != null) {
return objectArray[index];
} else if (primitiveArray instanceof long[] longArray) {
return longArray[index];
} else if (primitiveArray instanceof double[] doubleArray) {
return doubleArray[index];
}
}
throw new ArrayIndexOutOfBoundsException();
} catch (IndexOutOfBoundsException e) {
throw ArrayPanics.indexOutOfBounds(node, index, size);
}
}
/**
* Returns the current array of the builder.
*/
Object toArray() {
if (objectArray != null) {
return objectArray.length == size ? objectArray : Arrays.copyOf(objectArray, size);
} else if (primitiveArray instanceof long[] longArray) {
return longArray.length == size ? longArray : Arrays.copyOf(longArray, size);
} else if (primitiveArray instanceof double[] doubleArray) {
return doubleArray.length == size ? doubleArray : Arrays.copyOf(doubleArray, size);
} else {
return EMPTY_ARRAY;
}
}
int getSize() {
return size;
}
@ExportMessage
Object invokeMember(
String name, Object[] args,
@CachedLibrary(limit="3") InteropLibrary iop
) throws UnknownIdentifierException, UnsupportedTypeException, UnsupportedMessageException {
return switch (name) {
case "isEmpty" -> isEmpty();
case "add" -> {
add(args[0]);
yield this;
}
case "appendTo" -> {
long len = iop.getArraySize(args[0]);
for (var i = 0; i < len; i++) {
try {
var e = iop.readArrayElement(args[0], i);
add(e);
} catch (InvalidArrayIndexException ex) {
throw UnsupportedTypeException.create(args);
}
}
yield this;
}
case "get" -> {
if (!iop.isNumber(args[0])) {
throw UnsupportedTypeException.create(args);
}
if (!iop.fitsInInt(args[0])) {
throw UnsupportedTypeException.create(args);
}
var index = iop.asInt(args[0]);
yield get(index, iop);
}
case "getSize" -> getSize();
case "toArray" -> {
var arr = toArray();
if (arr instanceof long[] longs) {
yield Vector.fromLongArray(longs);
}
if (arr instanceof double[] doubles) {
yield Vector.fromDoubleArray(doubles);
}
yield Vector.fromInteropArray(new Array((Object[])arr));
}
default -> throw UnknownIdentifierException.create(name);
};
}
@ExportMessage
boolean hasMembers() {
return true;
}
@ExportMessage
boolean isMemberInvocable(String member) {
for (var m : MEMBERS) {
if (m.equals(member)) {
return true;
}
}
return false;
}
@ExportMessage
EnsoObject getMembers(boolean includeInternal) {
return ArrayLikeHelpers.wrapStrings(MEMBERS);
}
@ExportMessage
String toDisplayString(boolean ignore) {
return "Array_Builder";
}
}

View File

@ -0,0 +1,74 @@
package org.enso.interpreter.runtime.data.vector;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.NeverDefault;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.interop.InteropLibrary;
import com.oracle.truffle.api.interop.InvalidArrayIndexException;
import com.oracle.truffle.api.interop.UnsupportedMessageException;
import com.oracle.truffle.api.library.CachedLibrary;
import com.oracle.truffle.api.nodes.Node;
import org.enso.interpreter.node.expression.builtin.interop.syntax.HostValueToEnsoNode;
import org.enso.interpreter.runtime.error.WarningsLibrary;
public abstract class ArrayLikeAtNode extends Node {
public abstract Object executeAt(Object arrayLike, long index) throws InvalidArrayIndexException;
@NeverDefault
public static ArrayLikeAtNode create() {
return ArrayLikeAtNodeGen.create();
}
//
// implementation
//
@Specialization
Object arrayAt(Array self, long index) throws InvalidArrayIndexException {
try {
return self.getItems()[Math.toIntExact(index)];
} catch (ArithmeticException | IndexOutOfBoundsException ex) {
throw InvalidArrayIndexException.create(index, ex);
}
}
@Specialization
Object vectorLongAt(Vector.Long self, long index) throws InvalidArrayIndexException {
return self.readArrayElement(index);
}
@Specialization
Object vectorDoubleAt(Vector.Double self, long index) throws InvalidArrayIndexException {
return self.readArrayElement(index);
}
@Specialization
Object vectorAt(
Vector.Generic self,
long index,
@Cached.Exclusive @CachedLibrary(limit = "3") InteropLibrary interop,
@Cached.Exclusive @CachedLibrary(limit = "3") WarningsLibrary warnings,
@Cached.Exclusive @Cached HostValueToEnsoNode convert)
throws InvalidArrayIndexException {
try {
return self.readArrayElement(index, interop, warnings, convert);
} catch (UnsupportedMessageException ex) {
throw ArrayPanics.notAnArrayPanic(this, self);
}
}
@Specialization
Object genericAt(
Object self,
long index,
@Cached.Exclusive @CachedLibrary(limit = "3") InteropLibrary interop,
@Cached.Exclusive @Cached HostValueToEnsoNode convert)
throws InvalidArrayIndexException {
try {
var element = interop.readArrayElement(self, index);
return convert.execute(element);
} catch (UnsupportedMessageException ex) {
throw ArrayPanics.notAnArrayPanic(this, self);
}
}
}

View File

@ -1,4 +1,4 @@
package org.enso.interpreter.node.expression.builtin.mutable;
package org.enso.interpreter.runtime.data.vector;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.Fallback;
@ -10,19 +10,13 @@ import com.oracle.truffle.api.interop.UnsupportedMessageException;
import com.oracle.truffle.api.library.CachedLibrary;
import com.oracle.truffle.api.nodes.Node;
import org.enso.interpreter.node.expression.builtin.interop.syntax.HostValueToEnsoNode;
import org.enso.interpreter.runtime.EnsoContext;
import org.enso.interpreter.runtime.builtin.Builtins;
import org.enso.interpreter.runtime.callable.atom.Atom;
import org.enso.interpreter.runtime.data.Array;
import org.enso.interpreter.runtime.data.Vector;
import org.enso.interpreter.runtime.error.PanicException;
public abstract class CoerceArrayNode extends Node {
public abstract class ArrayLikeCoerceToArrayNode extends Node {
private @Child InteropLibrary library = InteropLibrary.getFactory().createDispatched(10);
@NeverDefault
public static CoerceArrayNode build() {
return CoerceArrayNodeGen.create();
public static ArrayLikeCoerceToArrayNode build() {
return ArrayLikeCoerceToArrayNodeGen.create();
}
public abstract Object[] execute(Object value);
@ -33,7 +27,7 @@ public abstract class CoerceArrayNode extends Node {
}
@Specialization
Object[] doVector(Vector arr, @Cached CoerceArrayNode coerceArrayNode) {
Object[] doVector(Vector.Generic arr, @Cached ArrayLikeCoerceToArrayNode coerceArrayNode) {
return coerceArrayNode.execute(arr.toArray());
}
@ -45,13 +39,9 @@ public abstract class CoerceArrayNode extends Node {
try {
return convertToArray(arr, hostValueToEnsoNode);
} catch (UnsupportedMessageException e) {
Builtins builtins = EnsoContext.get(this).getBuiltins();
Atom err = builtins.error().makeTypeError(builtins.array(), arr, "arr");
throw new PanicException(err, this);
throw ArrayPanics.typeError(this, arr, "arr");
} catch (InvalidArrayIndexException e) {
Builtins builtins = EnsoContext.get(this).getBuiltins();
throw new PanicException(
builtins.error().makeInvalidArrayIndex(arr, e.getInvalidIndex()), this);
throw ArrayPanics.invalidIndex(this, arr, e);
}
}
@ -67,8 +57,6 @@ public abstract class CoerceArrayNode extends Node {
@Fallback
Object[] doOther(Object arr) {
Builtins builtins = EnsoContext.get(this).getBuiltins();
Atom error = builtins.error().makeTypeError("array", arr, "arr");
throw new PanicException(error, this);
throw ArrayPanics.typeError(this, arr, "arr");
}
}

View File

@ -1,4 +1,4 @@
package org.enso.interpreter.node.expression.builtin.mutable;
package org.enso.interpreter.runtime.data.vector;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.Fallback;
@ -10,17 +10,15 @@ import com.oracle.truffle.api.library.CachedLibrary;
import com.oracle.truffle.api.nodes.Node;
import org.enso.interpreter.node.expression.builtin.interop.syntax.HostValueToEnsoNode;
import org.enso.interpreter.runtime.EnsoContext;
import org.enso.interpreter.runtime.builtin.Builtins;
import org.enso.interpreter.runtime.data.Array;
import org.enso.interpreter.runtime.error.PanicException;
import org.enso.interpreter.runtime.data.EnsoObject;
public abstract class CopyNode extends Node {
public static CopyNode build() {
return CopyNodeGen.create();
public abstract class ArrayLikeCopyToArrayNode extends Node {
public static ArrayLikeCopyToArrayNode build() {
return ArrayLikeCopyToArrayNodeGen.create();
}
public abstract Object execute(
Object src, long source_index, Array dest, long dest_index, long count);
Object src, long srcIndex, EnsoObject destArr, long destIndex, long count);
@Specialization
Object doArray(Array src, long source_index, Array dest, long dest_index, long count) {
@ -46,19 +44,13 @@ public abstract class CopyNode extends Node {
} catch (UnsupportedMessageException e) {
throw new IllegalStateException("Unreachable");
} catch (InvalidArrayIndexException e) {
throw new PanicException(
EnsoContext.get(this)
.getBuiltins()
.error()
.makeInvalidArrayIndex(src, e.getInvalidIndex()),
this);
throw ArrayPanics.invalidIndex(this, src, e);
}
return EnsoContext.get(this).getBuiltins().nothing();
}
@Fallback
Object doOther(Object src, long source_index, Array dest, long dest_index, long count) {
Builtins builtins = EnsoContext.get(this).getBuiltins();
throw new PanicException(builtins.error().makeTypeError(builtins.array(), src, "src"), this);
Object doOther(Object src, long source_index, EnsoObject dest, long dest_index, long count) {
throw ArrayPanics.typeError(this, src, "src");
}
}

View File

@ -0,0 +1,161 @@
package org.enso.interpreter.runtime.data.vector;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.frame.VirtualFrame;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.List;
import org.enso.interpreter.dsl.Builtin;
import org.enso.interpreter.node.callable.dispatch.InvokeFunctionNode;
import org.enso.interpreter.runtime.callable.function.Function;
import org.enso.interpreter.runtime.data.EnsoObject;
import org.enso.interpreter.runtime.error.DataflowError;
import org.enso.interpreter.runtime.error.WarningsLibrary;
import org.enso.interpreter.runtime.state.State;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.library.CachedLibrary;
/** Publicly available operations on array-like classes. */
@Builtin(pkg = "immutable", stdlibName = "Standard.Base.Internal.Array_Like_Helpers")
public final class ArrayLikeHelpers {
private ArrayLikeHelpers() {}
@Builtin.Method(
name = "new_array_proxy_builtin",
description = "Creates an array backed by a proxy object.")
@Builtin.WrapException(from = IllegalArgumentException.class)
public static EnsoObject create(long length, Object at) throws IllegalArgumentException {
return ArrayProxy.create(length, at);
}
/** Checks whether an array like object is considered immutable.
* Immutable objects are instances of {@link EnsoObject} and can be safely cast
* to that interface.
*
* @param obj the object to check
* @return if the {@code obj} is already seen as immutable
*/
public static boolean isImmutable(Object obj) {
return obj instanceof Vector;
}
/**
* 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;
}
/**
* Creates an uninitialized array of the given size.The values must be filled before the array is
* returned to Enso.
*
* @param size the size of the created array.
* @return the array instance
*/
public static EnsoObject allocate(long size) {
var arr = new Object[Math.toIntExact(size)];
return new Array(arr);
}
@Builtin.Method(
name = "vector_from_function",
description = "Creates new Vector with given length and provided elements.",
autoRegister = false)
@Builtin.Specialize()
public static Object vectorFromFunction(
VirtualFrame frame,
long length,
Function fun,
State state,
@Cached("buildWithArity(1)") InvokeFunctionNode invokeFunctionNode,
@CachedLibrary(limit="3") WarningsLibrary warnings
) {
var len = Math.toIntExact(length);
var target = ArrayBuilder.newBuilder(len);
boolean nonTrivialEnsoValue = false;
for (int i = 0; i < len; i++) {
var value = invokeFunctionNode.execute(fun, frame, state, new Long[] {(long) i});
if (value instanceof DataflowError) {
return value;
}
if (warnings.hasWarnings(value)) {
nonTrivialEnsoValue = true;
} else {
var isEnsoValue = value instanceof EnsoObject || value instanceof Long || value instanceof Double;
if (!isEnsoValue) {
nonTrivialEnsoValue = true;
}
}
target.add(value);
}
var res = target.toArray();
if (res instanceof long[] longs) {
return Vector.fromLongArray(longs);
}
if (res instanceof double[] doubles) {
return Vector.fromDoubleArray(doubles);
}
if (nonTrivialEnsoValue) {
return Vector.fromInteropArray(new Array((Object[])res));
} else {
return Vector.fromEnsoOnlyArray((Object[])res);
}
}
@Builtin.Method(
name = "vector_to_array",
description = "Returns an Array representation of this Vector.")
public static Object vectorToArray(Object obj) {
if (obj instanceof Vector.Generic vector) {
return vector.toArray();
} else {
return obj;
}
}
@Builtin.Method(
name = "new_vector_builder",
description = "Returns new vector builder.")
public static Object newVectorBuilder(long capacity) {
return ArrayBuilder.newBuilder((int)Math.min(Math.abs(capacity),Integer.MAX_VALUE));
}
public static EnsoObject wrapBuffer(ByteBuffer buffer) {
return ArrayOverBuffer.wrapBuffer(buffer);
}
public static EnsoObject wrapEnsoObjects(EnsoObject... arr) {
return new Array((Object[]) arr);
}
public static EnsoObject wrapStrings(String... arr) {
return new Array((Object[]) arr);
}
public static EnsoObject wrapObjectsWithCheckAt(Object... arr) {
return new Array((Object[]) arr);
}
public static EnsoObject empty() {
return allocate(0);
}
public static EnsoObject asVectorWithCheckAt(Object... arr) {
return Vector.fromInteropArray(new Array((Object[]) arr));
}
public static EnsoObject asVectorFromArray(Object storage) {
return Vector.fromInteropArray(storage);
}
}

View File

@ -0,0 +1,57 @@
package org.enso.interpreter.runtime.data.vector;
import com.oracle.truffle.api.dsl.Cached.Exclusive;
import com.oracle.truffle.api.dsl.Fallback;
import com.oracle.truffle.api.dsl.NeverDefault;
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;
public abstract class ArrayLikeLengthNode extends Node {
public abstract long executeLength(Object arrayLike);
@NeverDefault
public static ArrayLikeLengthNode create() {
return ArrayLikeLengthNodeGen.create();
}
//
// implementation
//
@Specialization
static long arrayLength(Array self) {
return self.length();
}
@Specialization
static long vectorLongLength(Vector.Long self) {
return self.getArraySize();
}
@Specialization
static long vectorDoubleLength(Vector.Double self) {
return self.getArraySize();
}
@Specialization
long vectorLength(
Vector.Generic self, @Exclusive @CachedLibrary(limit = "3") InteropLibrary iop) {
try {
return self.getArraySize(iop);
} catch (UnsupportedMessageException ex) {
throw ArrayPanics.notAnArrayPanic(this, self);
}
}
@Fallback
long foreignLength(Object self, @Exclusive @CachedLibrary(limit = "3") InteropLibrary iop) {
try {
return iop.getArraySize(self);
} catch (UnsupportedMessageException ex) {
throw ArrayPanics.notAnArrayPanic(this, self);
}
}
}

View File

@ -1,14 +1,14 @@
package org.enso.interpreter.runtime.data;
package org.enso.interpreter.runtime.data.vector;
import com.oracle.truffle.api.interop.InteropLibrary;
import com.oracle.truffle.api.interop.InvalidArrayIndexException;
import com.oracle.truffle.api.interop.TruffleObject;
import com.oracle.truffle.api.library.ExportLibrary;
import com.oracle.truffle.api.library.ExportMessage;
import java.nio.ByteBuffer;
import org.enso.interpreter.runtime.data.EnsoObject;
@ExportLibrary(InteropLibrary.class)
public final class ArrayOverBuffer implements TruffleObject {
final class ArrayOverBuffer implements EnsoObject {
private final ByteBuffer buffer;
private ArrayOverBuffer(ByteBuffer buffer) {
@ -39,7 +39,7 @@ public final class ArrayOverBuffer implements TruffleObject {
return buffer.remaining();
}
public static ArrayOverBuffer wrapBuffer(ByteBuffer buffer) {
static ArrayOverBuffer wrapBuffer(ByteBuffer buffer) {
return new ArrayOverBuffer(buffer);
}

View File

@ -0,0 +1,43 @@
package org.enso.interpreter.runtime.data.vector;
import com.oracle.truffle.api.interop.InvalidArrayIndexException;
import com.oracle.truffle.api.nodes.Node;
import org.enso.interpreter.runtime.EnsoContext;
import org.enso.interpreter.runtime.error.PanicException;
final class ArrayPanics {
private ArrayPanics() {}
static PanicException notAnArrayPanic(Node node, Object self) {
var ctx = EnsoContext.get(node);
var err =
ctx.getBuiltins()
.error()
.makeUnsupportedArgumentsError(new Object[] {self}, "Not an array");
return new PanicException(err, node);
}
static PanicException unsupportedArgument(Node node, Object arg, String msg) {
var ctx = EnsoContext.get(node);
var err = ctx.getBuiltins().error().makeUnsupportedArgumentsError(new Object[] {arg}, msg);
return new PanicException(err, node);
}
static PanicException indexOutOfBounds(Node node, int index, int size) {
var ctx = EnsoContext.get(node);
var err = ctx.getBuiltins().error().makeIndexOutOfBounds(index, size);
throw new PanicException(err, node);
}
static PanicException invalidIndex(Node node, Object src, InvalidArrayIndexException e) {
var ctx = EnsoContext.get(node);
var err = ctx.getBuiltins().error().makeInvalidArrayIndex(src, e.getInvalidIndex());
return new PanicException(err, node);
}
static PanicException typeError(Node node, Object src, String msg) {
var builtins = EnsoContext.get(node).getBuiltins();
var err = builtins.error().makeTypeError(builtins.array(), src, msg);
return new PanicException(err, node);
}
}

View File

@ -1,4 +1,4 @@
package org.enso.interpreter.runtime.data;
package org.enso.interpreter.runtime.data.vector;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.dsl.Cached;
@ -6,16 +6,15 @@ import com.oracle.truffle.api.dsl.ImportStatic;
import com.oracle.truffle.api.interop.ArityException;
import com.oracle.truffle.api.interop.InteropLibrary;
import com.oracle.truffle.api.interop.InvalidArrayIndexException;
import com.oracle.truffle.api.interop.TruffleObject;
import com.oracle.truffle.api.interop.UnsupportedMessageException;
import com.oracle.truffle.api.interop.UnsupportedTypeException;
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.profiles.BranchProfile;
import org.enso.interpreter.dsl.Builtin;
import org.enso.interpreter.runtime.EnsoContext;
import org.enso.interpreter.runtime.error.PanicException;
import org.enso.interpreter.runtime.data.EnsoObject;
import org.enso.interpreter.runtime.data.Type;
import org.enso.interpreter.runtime.library.dispatch.TypesLibrary;
/**
@ -26,9 +25,8 @@ import org.enso.interpreter.runtime.library.dispatch.TypesLibrary;
*/
@ExportLibrary(InteropLibrary.class)
@ExportLibrary(TypesLibrary.class)
@Builtin(pkg = "immutable", stdlibName = "Standard.Base.Data.Array_Proxy.Array_Proxy")
@ImportStatic(BranchProfile.class)
public final class ArrayProxy implements TruffleObject {
final class ArrayProxy implements EnsoObject {
private final long length;
private final Object at;
@ -36,9 +34,8 @@ public final class ArrayProxy implements TruffleObject {
if (CompilerDirectives.inInterpreter()) {
InteropLibrary interop = InteropLibrary.getUncached();
if (!interop.isExecutable(at)) {
throw new PanicException(
EnsoContext.get(interop).getBuiltins().error().makeTypeError("Function", at, "at"),
interop);
var msg = "Array_Proxy needs executable function.";
throw ArrayPanics.typeError(interop, at, msg);
}
}
@ -51,9 +48,7 @@ public final class ArrayProxy implements TruffleObject {
this.at = at;
}
@Builtin.Method(name = "new_builtin", description = "Creates an array backed by a proxy object.")
@Builtin.WrapException(from = IllegalArgumentException.class)
public static ArrayProxy create(long length, Object at) throws IllegalArgumentException {
static ArrayProxy create(long length, Object at) throws IllegalArgumentException {
return new ArrayProxy(length, at);
}

View File

@ -1,25 +1,26 @@
package org.enso.interpreter.runtime.data;
package org.enso.interpreter.runtime.data.vector;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.Cached.Shared;
import com.oracle.truffle.api.interop.InteropLibrary;
import com.oracle.truffle.api.interop.TruffleObject;
import com.oracle.truffle.api.interop.InvalidArrayIndexException;
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 org.enso.interpreter.node.expression.builtin.interop.syntax.HostValueToEnsoNode;
import org.enso.interpreter.runtime.EnsoContext;
import org.enso.interpreter.runtime.data.EnsoObject;
import org.enso.interpreter.runtime.error.Warning;
import org.enso.interpreter.runtime.error.WarningsLibrary;
import org.enso.interpreter.runtime.error.WithWarnings;
@ExportLibrary(InteropLibrary.class)
@ExportLibrary(WarningsLibrary.class)
public final class ArraySlice implements TruffleObject {
final class ArraySlice implements EnsoObject {
private final Object storage;
private final long start;
private final long end;
@ -47,13 +48,13 @@ public final class ArraySlice implements TruffleObject {
long slice_end = Math.min(this_length, end);
Object slice;
if (slice_start >= slice_end) {
slice = Array.allocate(0);
slice = ArrayLikeHelpers.allocate(0);
} else if ((slice_start == 0) && (slice_end == this_length)) {
return null;
} else {
slice = new ArraySlice(storage, slice_start, slice_end);
}
return Vector.fromArray(slice);
return Vector.fromInteropArray(slice);
}
/**

View File

@ -1,4 +1,4 @@
package org.enso.interpreter.runtime.data;
package org.enso.interpreter.runtime.data.vector;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.interop.InteropLibrary;
@ -7,7 +7,8 @@ import com.oracle.truffle.api.interop.UnsupportedMessageException;
import java.io.PrintWriter;
import java.io.StringWriter;
public class DisplayArrayUtils {
final class DisplayArrayUtils {
private DisplayArrayUtils() {}
@CompilerDirectives.TruffleBoundary
public static String toDisplayString(

View File

@ -0,0 +1,395 @@
package org.enso.interpreter.runtime.data.vector;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.interop.InteropLibrary;
import com.oracle.truffle.api.interop.InvalidArrayIndexException;
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 org.enso.interpreter.dsl.Builtin;
import org.enso.interpreter.node.expression.builtin.interop.syntax.HostValueToEnsoNode;
import org.enso.interpreter.runtime.EnsoContext;
import org.enso.interpreter.runtime.data.EnsoObject;
import org.enso.interpreter.runtime.data.Type;
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;
@ExportLibrary(InteropLibrary.class)
@ExportLibrary(TypesLibrary.class)
@Builtin(pkg = "immutable", stdlibName = "Standard.Base.Data.Vector.Vector")
abstract class Vector implements EnsoObject {
@ExportMessage
boolean hasArrayElements() {
return true;
}
@ExportMessage
boolean isArrayElementModifiable(long index) {
return false;
}
@ExportMessage
boolean isArrayElementReadable(long index) {
return true;
}
@ExportMessage
long getArraySize() {
throw CompilerDirectives.shouldNotReachHere();
}
@ExportMessage
Object readArrayElement(long index)
throws UnsupportedMessageException, InvalidArrayIndexException {
throw CompilerDirectives.shouldNotReachHere();
}
@ExportMessage
final void writeArrayElement(long index, Object value) throws UnsupportedMessageException {
throw UnsupportedMessageException.create();
}
@ExportMessage
boolean isArrayElementInsertable(long index) {
return false;
}
@ExportMessage
boolean isArrayElementRemovable(long index) {
return false;
}
@ExportMessage
final void removeArrayElement(long index) throws UnsupportedMessageException {
throw UnsupportedMessageException.create();
}
@ExportMessage
@CompilerDirectives.TruffleBoundary
String toDisplayString(boolean allowSideEffects) {
final InteropLibrary iop = InteropLibrary.getUncached();
return DisplayArrayUtils.toDisplayString(this, allowSideEffects, iop);
}
@ExportMessage
Type getMetaObject(@CachedLibrary("this") InteropLibrary thisLib) {
return EnsoContext.get(thisLib).getBuiltins().vector();
}
@ExportMessage
boolean hasMetaObject() {
return true;
}
//
// methods for TypesLibrary
//
@ExportMessage
boolean hasType() {
return true;
}
@ExportMessage
Type getType(@CachedLibrary("this") TypesLibrary thisLib, @Cached("1") int ignore) {
return EnsoContext.get(thisLib).getBuiltins().vector();
}
//
// helper methods
//
@Override
@CompilerDirectives.TruffleBoundary
public String toString() {
return toDisplayString(false);
}
static Vector fromInteropArray(Object arr) {
return new Generic(arr);
}
static Vector fromLongArray(long[] arr) {
return new Long(arr);
}
static Vector fromDoubleArray(double[] arr) {
return new Double(arr);
}
static Object fromEnsoOnlyArray(Object[] arr) {
return new EnsoOnly(arr);
}
@ExportLibrary(InteropLibrary.class)
@ExportLibrary(WarningsLibrary.class)
static final class EnsoOnly extends Vector {
private final Object[] storage;
private EnsoOnly(Object[] storage) {
this.storage = storage;
}
//
// messages for the InteropLibrary
//
@ExportMessage
long getArraySize() {
return storage.length;
}
@ExportMessage
Object readArrayElement(long index) throws InvalidArrayIndexException {
try {
return storage[Math.toIntExact(index)];
} catch (ArithmeticException | IndexOutOfBoundsException ex) {
throw InvalidArrayIndexException.create(index);
}
}
@ExportMessage
boolean isArrayElementReadable(long index) {
var size = storage.length;
return index < size && index >= 0;
}
@ExportMessage
boolean hasWarnings() {
return false;
}
@ExportMessage
Warning[] getWarnings(Node location) throws UnsupportedMessageException {
return new Warning[0];
}
@ExportMessage
EnsoOnly removeWarnings() throws UnsupportedMessageException {
return this;
}
@ExportMessage
boolean isLimitReached() {
return false;
}
}
@ExportLibrary(InteropLibrary.class)
@ExportLibrary(WarningsLibrary.class)
static final class Generic extends Vector {
private final Object storage;
private Generic(Object storage) {
if (CompilerDirectives.inInterpreter()) {
if (!InteropLibrary.getUncached().hasArrayElements(storage)) {
throw new IllegalStateException("Vector needs array-like delegate, but got: " + storage);
}
}
this.storage = storage;
}
final Object toArray() {
return this.storage;
}
//
// messages for the InteropLibrary
//
@ExportMessage
long getArraySize(
@Cached.Shared(value = "interop") @CachedLibrary(limit = "3") InteropLibrary interop)
throws UnsupportedMessageException {
return interop.getArraySize(storage);
}
/**
* Handles reading an element by index through the polyglot API.
*
* @param index the index to read
* @return the element value at the provided index
* @throws InvalidArrayIndexException when the index is out of bounds.
*/
@ExportMessage
Object readArrayElement(
long index,
@Cached.Shared(value = "interop") @CachedLibrary(limit = "3") InteropLibrary interop,
@CachedLibrary(limit = "3") WarningsLibrary warnings,
@Cached HostValueToEnsoNode toEnso)
throws InvalidArrayIndexException, UnsupportedMessageException {
var v = interop.readArrayElement(this.storage, index);
if (warnings.hasWarnings(this.storage)) {
Warning[] extracted = warnings.getWarnings(this.storage, null);
if (warnings.hasWarnings(v)) {
v = warnings.removeWarnings(v);
}
return WithWarnings.wrap(EnsoContext.get(interop), toEnso.execute(v), extracted);
}
return toEnso.execute(v);
}
/**
* Exposes an index validity check through the polyglot API.
*
* @param index the index to check
* @return {@code true} if the index is valid, {@code false} otherwise.
*/
@ExportMessage
boolean isArrayElementReadable(
long index,
@Cached.Shared(value = "interop") @CachedLibrary(limit = "3") InteropLibrary interop) {
try {
var size = interop.getArraySize(storage);
return index < size && index >= 0;
} catch (UnsupportedMessageException e) {
return false;
}
}
@ExportMessage
boolean hasWarnings(
@Cached.Shared(value = "warnsLib") @CachedLibrary(limit = "3") WarningsLibrary warnings) {
return warnings.hasWarnings(this.storage);
}
@ExportMessage
Warning[] getWarnings(
Node location,
@Cached.Shared(value = "warnsLib") @CachedLibrary(limit = "3") WarningsLibrary warnings)
throws UnsupportedMessageException {
return warnings.getWarnings(this.storage, location);
}
@ExportMessage
Generic removeWarnings(
@Cached.Shared(value = "warnsLib") @CachedLibrary(limit = "3") WarningsLibrary warnings)
throws UnsupportedMessageException {
return new Generic(warnings.removeWarnings(this.storage));
}
@ExportMessage
boolean isLimitReached(
@Cached.Shared(value = "warnsLib") @CachedLibrary(limit = "3") WarningsLibrary warnings) {
return warnings.isLimitReached(this.storage);
}
}
@ExportLibrary(value = InteropLibrary.class)
@ExportLibrary(value = WarningsLibrary.class)
static final class Double extends Vector {
private final double[] storage;
private Double(double[] storage) {
this.storage = storage;
}
@ExportMessage
long getArraySize() {
return storage.length;
}
/**
* Handles reading an element by index through the polyglot API.
*
* @param index the index to read
* @return the element value at the provided index
* @throws InvalidArrayIndexException when the index is out of bounds.
*/
@ExportMessage
Object readArrayElement(long index) throws InvalidArrayIndexException {
try {
return storage[Math.toIntExact(index)];
} catch (ArithmeticException | IndexOutOfBoundsException ex) {
throw InvalidArrayIndexException.create(index);
}
}
/**
* Exposes an index validity check through the polyglot API.
*
* @param index the index to check
* @return {@code true} if the index is valid, {@code false} otherwise.
*/
@ExportMessage
boolean isArrayElementReadable(long index) {
var size = storage.length;
return index < size && index >= 0;
}
@ExportMessage
boolean hasWarnings() {
return false;
}
@ExportMessage
Warning[] getWarnings(Node location) throws UnsupportedMessageException {
return new Warning[0];
}
@ExportMessage
Double removeWarnings() {
return this;
}
@ExportMessage
boolean isLimitReached() {
return false;
}
}
@ExportLibrary(value = InteropLibrary.class)
@ExportLibrary(value = WarningsLibrary.class)
static final class Long extends Vector {
private final long[] storage;
private Long(long[] storage) {
this.storage = storage;
}
@ExportMessage
long getArraySize() {
return storage.length;
}
@ExportMessage
Object readArrayElement(long index) throws InvalidArrayIndexException {
try {
return storage[Math.toIntExact(index)];
} catch (ArithmeticException | IndexOutOfBoundsException ex) {
throw InvalidArrayIndexException.create(index);
}
}
@ExportMessage
boolean isArrayElementReadable(long index) {
var size = storage.length;
return index < size && index >= 0;
}
@ExportMessage
boolean hasWarnings() {
return false;
}
@ExportMessage
Warning[] getWarnings(Node location) throws UnsupportedMessageException {
return new Warning[0];
}
@ExportMessage
Long removeWarnings() {
return this;
}
@ExportMessage
boolean isLimitReached() {
return false;
}
}
}

View File

@ -4,7 +4,6 @@ import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.interop.InteropLibrary;
import com.oracle.truffle.api.interop.InvalidArrayIndexException;
import com.oracle.truffle.api.interop.TruffleObject;
import com.oracle.truffle.api.interop.UnsupportedMessageException;
import com.oracle.truffle.api.library.CachedLibrary;
import com.oracle.truffle.api.library.ExportLibrary;
@ -16,15 +15,16 @@ import java.util.Arrays;
import java.util.Comparator;
import org.enso.interpreter.dsl.Builtin;
import org.enso.interpreter.runtime.EnsoContext;
import org.enso.interpreter.runtime.data.Array;
import org.enso.interpreter.runtime.data.ArrayRope;
import org.enso.interpreter.runtime.data.EnsoObject;
import org.enso.interpreter.runtime.data.Type;
import org.enso.interpreter.runtime.data.vector.ArrayLikeHelpers;
import org.enso.interpreter.runtime.library.dispatch.TypesLibrary;
import org.graalvm.collections.EconomicSet;
@Builtin(pkg = "error", stdlibName = "Standard.Base.Warning.Warning")
@ExportLibrary(TypesLibrary.class)
public final class Warning implements TruffleObject {
public final class Warning implements EnsoObject {
private final Object value;
private final Object origin;
private final ArrayRope<Reassignment> reassignments;
@ -62,9 +62,9 @@ public final class Warning implements TruffleObject {
}
@Builtin.Method(description = "Gets the list of locations where the warnings was reassigned.")
public Array getReassignments() {
public EnsoObject getReassignments() {
Warning.Reassignment[] reassignmentsArray = reassignments.toArray(Warning.Reassignment[]::new);
return new Array(Arrays.copyOf(reassignmentsArray, reassignmentsArray.length, Object[].class));
return ArrayLikeHelpers.wrapEnsoObjects(reassignmentsArray);
}
@Builtin.Method(
@ -92,10 +92,10 @@ public final class Warning implements TruffleObject {
autoRegister = false)
@Builtin.Specialize
@CompilerDirectives.TruffleBoundary
public static Array getAll(WithWarnings value, WarningsLibrary warningsLib) {
public static EnsoObject getAll(WithWarnings value, WarningsLibrary warningsLib) {
Warning[] warnings = value.getWarningsArray(warningsLib);
sortArray(warnings);
return new Array((Object[]) warnings);
return ArrayLikeHelpers.wrapEnsoObjects(warnings);
}
@Builtin.Method(
@ -103,17 +103,17 @@ public final class Warning implements TruffleObject {
description = "Gets all the warnings associated with the value.",
autoRegister = false)
@Builtin.Specialize(fallback = true)
public static Array getAll(Object value, WarningsLibrary warnings) {
public static EnsoObject getAll(Object value, WarningsLibrary warnings) {
if (warnings.hasWarnings(value)) {
try {
Warning[] arr = warnings.getWarnings(value, null);
sortArray(arr);
return new Array((Object[]) arr);
return ArrayLikeHelpers.wrapEnsoObjects(arr);
} catch (UnsupportedMessageException e) {
throw new IllegalStateException(e);
}
} else {
return new Array();
return ArrayLikeHelpers.empty();
}
}
@ -190,7 +190,7 @@ public final class Warning implements TruffleObject {
}
@ExportLibrary(InteropLibrary.class)
public static final class Reassignment implements TruffleObject {
public static final class Reassignment implements EnsoObject {
private final String methodName;
private final SourceSection location;

View File

@ -2,11 +2,12 @@ package org.enso.interpreter.runtime.error;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.dsl.Cached.Shared;
import org.enso.interpreter.runtime.EnsoContext;
import org.enso.interpreter.runtime.data.ArrayRope;
import org.enso.interpreter.runtime.data.EnsoObject;
import org.enso.interpreter.runtime.library.dispatch.TypesLibrary;
import com.oracle.truffle.api.interop.TruffleObject;
import com.oracle.truffle.api.interop.UnsupportedMessageException;
import com.oracle.truffle.api.library.CachedLibrary;
import com.oracle.truffle.api.library.ExportLibrary;
@ -14,14 +15,14 @@ import com.oracle.truffle.api.library.ExportMessage;
import com.oracle.truffle.api.library.Message;
import com.oracle.truffle.api.library.ReflectionLibrary;
import com.oracle.truffle.api.nodes.Node;
import org.enso.polyglot.RuntimeOptions;
import org.graalvm.collections.EconomicSet;
import org.graalvm.collections.Equivalence;
@ExportLibrary(TypesLibrary.class)
@ExportLibrary(WarningsLibrary.class)
@ExportLibrary(ReflectionLibrary.class)
public final class WithWarnings implements TruffleObject {
public final class WithWarnings implements EnsoObject {
private final EconomicSet<Warning> warnings;
private final Object value;

View File

@ -3,13 +3,13 @@ package org.enso.interpreter.runtime.number;
import java.math.BigInteger;
import org.enso.interpreter.runtime.EnsoContext;
import org.enso.interpreter.runtime.data.EnsoObject;
import org.enso.interpreter.runtime.data.Type;
import org.enso.interpreter.runtime.library.dispatch.TypesLibrary;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.interop.InteropLibrary;
import com.oracle.truffle.api.interop.TruffleObject;
import com.oracle.truffle.api.interop.UnsupportedMessageException;
import com.oracle.truffle.api.library.CachedLibrary;
import com.oracle.truffle.api.library.ExportLibrary;
@ -18,7 +18,7 @@ import com.oracle.truffle.api.library.ExportMessage;
/** Internal wrapper for a {@link BigInteger}. */
@ExportLibrary(InteropLibrary.class)
@ExportLibrary(TypesLibrary.class)
public final class EnsoBigInteger implements TruffleObject {
public final class EnsoBigInteger implements EnsoObject {
private final BigInteger value;
/**

View File

@ -4,7 +4,6 @@ import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.TruffleLanguage;
import com.oracle.truffle.api.frame.MaterializedFrame;
import com.oracle.truffle.api.interop.InteropLibrary;
import com.oracle.truffle.api.interop.TruffleObject;
import com.oracle.truffle.api.interop.UnknownIdentifierException;
import com.oracle.truffle.api.interop.UnsupportedMessageException;
import com.oracle.truffle.api.library.ExportLibrary;
@ -19,6 +18,7 @@ import java.util.stream.Collectors;
import org.enso.interpreter.EnsoLanguage;
import org.enso.interpreter.node.EnsoRootNode;
import org.enso.interpreter.runtime.callable.function.Function;
import org.enso.interpreter.runtime.data.EnsoObject;
import org.enso.interpreter.runtime.error.DataflowError;
/**
@ -33,7 +33,7 @@ import org.enso.interpreter.runtime.error.DataflowError;
* </ul>
*/
@ExportLibrary(InteropLibrary.class)
public class DebugLocalScope implements TruffleObject {
public class DebugLocalScope implements EnsoObject {
private final EnsoRootNode rootNode;
/** All the bindings, including the parent scopes. */
@ -262,7 +262,7 @@ public class DebugLocalScope implements TruffleObject {
/** Simple interop wrapper for a list of strings. */
@ExportLibrary(InteropLibrary.class)
static final class ScopeMembers implements TruffleObject {
static final class ScopeMembers implements EnsoObject {
private final List<String> memberNames;
ScopeMembers(List<String> memberNames) {

View File

@ -1,7 +1,6 @@
package org.enso.interpreter.runtime.scope;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.interop.TruffleObject;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
@ -12,12 +11,13 @@ import java.util.Optional;
import java.util.Set;
import org.enso.interpreter.runtime.Module;
import org.enso.interpreter.runtime.callable.function.Function;
import org.enso.interpreter.runtime.data.EnsoObject;
import org.enso.interpreter.runtime.data.Type;
import org.enso.interpreter.runtime.error.RedefinedConversionException;
import org.enso.interpreter.runtime.error.RedefinedMethodException;
/** A representation of Enso's per-file top-level scope. */
public final class ModuleScope implements TruffleObject {
public final class ModuleScope implements EnsoObject {
private final Type associatedType;
private final Module module;
private Map<String, Object> polyglotSymbols;

View File

@ -5,7 +5,6 @@ import com.oracle.truffle.api.TruffleFile;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.interop.ArityException;
import com.oracle.truffle.api.interop.InteropLibrary;
import com.oracle.truffle.api.interop.TruffleObject;
import com.oracle.truffle.api.interop.UnknownIdentifierException;
import com.oracle.truffle.api.interop.UnsupportedMessageException;
import com.oracle.truffle.api.interop.UnsupportedTypeException;
@ -20,7 +19,8 @@ import org.enso.interpreter.EnsoLanguage;
import org.enso.interpreter.runtime.EnsoContext;
import org.enso.interpreter.runtime.Module;
import org.enso.interpreter.runtime.builtin.Builtins;
import org.enso.interpreter.runtime.data.Array;
import org.enso.interpreter.runtime.data.EnsoObject;
import org.enso.interpreter.runtime.data.vector.ArrayLikeHelpers;
import org.enso.interpreter.runtime.type.Types;
import org.enso.interpreter.util.ScalaConversions;
import org.enso.pkg.Package;
@ -30,7 +30,7 @@ import org.enso.polyglot.RuntimeOptions;
/** Represents the top scope of Enso execution, containing all the importable modules. */
@ExportLibrary(InteropLibrary.class)
public final class TopLevelScope implements TruffleObject {
public final class TopLevelScope implements EnsoObject {
private final Builtins builtins;
private final PackageRepository packageRepository;
@ -107,8 +107,8 @@ public final class TopLevelScope implements TruffleObject {
* @return a collection of all the exported members.
*/
@ExportMessage
Array getMembers(boolean includeInternal) {
return new Array(
EnsoObject getMembers(boolean includeInternal) {
return ArrayLikeHelpers.wrapStrings(
MethodNames.TopScope.GET_MODULE,
MethodNames.TopScope.CREATE_MODULE,
MethodNames.TopScope.REGISTER_MODULE,

View File

@ -12,11 +12,11 @@ import java.io.OutputStream;
import org.apache.commons.lang3.SystemUtils;
import org.enso.interpreter.EnsoLanguage;
import org.enso.interpreter.dsl.Builtin;
import org.enso.interpreter.node.expression.builtin.mutable.CoerceArrayNode;
import org.enso.interpreter.node.expression.builtin.text.util.ExpectStringNode;
import org.enso.interpreter.runtime.EnsoContext;
import org.enso.interpreter.runtime.callable.atom.Atom;
import org.enso.interpreter.runtime.data.text.Text;
import org.enso.interpreter.runtime.data.vector.ArrayLikeCoerceToArrayNode;
public class System {
@ -72,7 +72,7 @@ public class System {
boolean redirectIn,
boolean redirectOut,
boolean redirectErr,
@Cached CoerceArrayNode coerce,
@Cached ArrayLikeCoerceToArrayNode coerce,
@Cached ExpectStringNode expectStringNode)
throws IOException, InterruptedException {
Object[] arrArguments = coerce.execute(arguments);

View File

@ -8,9 +8,6 @@ import org.enso.interpreter.runtime.callable.UnresolvedSymbol;
import org.enso.interpreter.runtime.callable.atom.Atom;
import org.enso.interpreter.runtime.callable.atom.AtomConstructor;
import org.enso.interpreter.runtime.callable.function.Function;
import org.enso.interpreter.runtime.data.Array;
import org.enso.interpreter.runtime.data.ArrayOverBuffer;
import org.enso.interpreter.runtime.data.ArrayProxy;
import org.enso.interpreter.runtime.data.EnsoDate;
import org.enso.interpreter.runtime.data.EnsoDateTime;
import org.enso.interpreter.runtime.data.EnsoDuration;
@ -20,7 +17,6 @@ import org.enso.interpreter.runtime.data.EnsoTimeZone;
import org.enso.interpreter.runtime.data.ManagedResource;
import org.enso.interpreter.runtime.data.Ref;
import org.enso.interpreter.runtime.data.Type;
import org.enso.interpreter.runtime.data.Vector;
import org.enso.interpreter.runtime.data.hash.EnsoHashMap;
import org.enso.interpreter.runtime.data.text.Text;
import org.enso.interpreter.runtime.error.DataflowError;
@ -53,16 +49,12 @@ import org.enso.polyglot.data.TypeGraph;
DataflowError.class,
UnresolvedConversion.class,
UnresolvedSymbol.class,
Array.class,
ArrayProxy.class,
ArrayOverBuffer.class,
EnsoBigInteger.class,
ManagedResource.class,
ModuleScope.class,
Ref.class,
PanicException.class,
PanicSentinel.class,
Vector.class,
EnsoHashMap.class,
Warning.class,
EnsoFile.class,

View File

@ -96,6 +96,7 @@ public class MetaObjectTest extends TestBase {
expecting.add(s);
}
}
expecting.remove(ConstantsGen.ARRAY_LIKE_HELPERS);
var w = new StringBuilder();
var f = new StringWriter();
var err = new PrintWriter(f);

View File

@ -522,12 +522,13 @@ class ValuesGenerator {
public List<Value> arrayLike() {
var collect = new ArrayList<Value>();
if (languages.contains(Language.ENSO)) {
collect.add(v(null, "", "[1, 2, 3]").type());
collect.add(v(null, "", "['a', 'b']").type());
collect.add(v(null, "", "[]").type());
collect.add(v(null, "", "[1, 2, 3].to_array").type());
collect.add(v(null, "", "['a', 'b'].to_array").type());
collect.add(v(null, "", "[].to_array").type());
var im = "from Standard.Base import Vector";
collect.add(v(null, im, "[1, 2, 3]").type());
collect.add(v(null, im, "['a', 'b']").type());
collect.add(v(null, im, "[]").type());
collect.add(v(null, im, "[1, 2, 3].to_array").type());
collect.add(v(null, im, "['a', 'b'].to_array").type());
collect.add(v(null, im, "[].to_array").type());
collect.add(v(null, """
import Standard.Base.Data.Array_Proxy.Array_Proxy
""", "Array_Proxy.new 10 (x -> 2 * x)").type());

View File

@ -116,7 +116,13 @@ public final class ExecuteMethodImplGenerator extends MethodGenerator {
};
case ARRAY:
return new String[] {
" return new Array((Object[]) " + qual + "." + name + "(" + paramsApplied + "));"
" return ArrayLikeHelpers.wrapObjects("
+ qual
+ "."
+ name
+ "("
+ paramsApplied
+ "));"
};
default:
if (returnTpe.isValidGuestType()) {

View File

@ -6,7 +6,7 @@ import java.io.PrintWriter;
import java.util.Arrays;
import java.util.List;
import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.element.*;
import javax.lang.model.element.Element;
import javax.tools.JavaFileObject;
import org.enso.interpreter.dsl.Builtin;
@ -148,6 +148,5 @@ public abstract class MethodNodeClassGenerator {
"org.enso.interpreter.node.expression.builtin.text.util.ExpectStringNode",
"org.enso.interpreter.runtime.EnsoContext",
"org.enso.interpreter.runtime.builtin.Builtins",
"org.enso.interpreter.runtime.data.Array",
"org.enso.interpreter.runtime.error.PanicException");
}

View File

@ -278,7 +278,13 @@ public final class SpecializedMethodsGenerator extends MethodGenerator {
break;
case ARRAY:
methodBody.add(
" return new Array((Object[]) " + qual + "." + name + "(" + paramsApplied + "));");
" return ArrayLikeHelpers.wrapObjects("
+ qual
+ "."
+ name
+ "("
+ paramsApplied
+ "));");
break;
default:
if (returnTpe.isValidGuestType()) {

View File

@ -39,13 +39,14 @@ public record TypeWithKind(String baseType, TypeKind kind) {
*/
private final static List<String> validGuestTypes =
List.of(
"org.enso.interpreter.runtime.data.EnsoObject",
"org.enso.interpreter.runtime.callable.atom.Atom",
"org.enso.interpreter.runtime.callable.function.Function",
"org.enso.interpreter.runtime.data.Array",
"org.enso.interpreter.runtime.data.Vector",
"org.enso.interpreter.runtime.data.hash.EnsoHashMap",
"org.enso.interpreter.runtime.data.ArrayOverBuffer",
"org.enso.interpreter.runtime.data.ArrayProxy",
"org.enso.interpreter.runtime.data.vector.Array",
"org.enso.interpreter.runtime.data.vector.Vector",
"org.enso.interpreter.runtime.data.vector.ArrayOverBuffer",
"org.enso.interpreter.runtime.data.vector.ArrayProxy",
"org.enso.interpreter.runtime.data.EnsoFile",
"org.enso.interpreter.runtime.data.EnsoDate",
"org.enso.interpreter.runtime.data.EnsoDateTime",

View File

@ -1,134 +0,0 @@
package org.enso.base;
import java.util.Arrays;
import java.util.List;
public class Array_Builder<T> {
private static final Object[] EMPTY_ARRAY = new Object[0];
private final int initialCapacity;
private int size;
private Object primitiveArray;
private Object[] objectArray;
private Array_Builder(int initialCapacity) {
this.initialCapacity = Math.max(1, initialCapacity);
}
/**
* This function forces the polyglot conversion of an Enso array into a `byte[]`. This allows for
* asserting that it is a valid `byte[]`.
*
* @param input the converted array.
* @return the `input` unchanged.
*/
public static byte[] ensureByteArray(byte[] input) {
return input;
}
/** Creates new builder */
public static <V> Array_Builder<V> newBuilder(int capacity) {
return new Array_Builder<>(capacity);
}
/** Is the builder empty? */
public boolean isEmpty() {
return size == 0;
}
/**
* Adds an element to the builder
*
* @param e the element to add
*/
public void add(T e) {
if (objectArray != null) {
if (size == objectArray.length) {
objectArray = Arrays.copyOf(objectArray, size * 2);
}
objectArray[size++] = e;
} else if (primitiveArray instanceof long[] longArray) {
if (e instanceof Long l) {
if (size == longArray.length) {
primitiveArray = longArray = Arrays.copyOf(longArray, size * 2);
}
longArray[size++] = l;
} else {
objectArray = new Object[longArray.length];
for (int i = 0; i < size; i++) {
objectArray[i] = longArray[i];
}
primitiveArray = null;
add(e);
}
} else if (primitiveArray instanceof double[] doubleArray) {
if (e instanceof Double d) {
if (size == doubleArray.length) {
primitiveArray = doubleArray = Arrays.copyOf(doubleArray, size * 2);
}
doubleArray[size++] = d;
} else {
objectArray = new Object[doubleArray.length];
for (int i = 0; i < size; i++) {
objectArray[i] = doubleArray[i];
}
primitiveArray = null;
add(e);
}
} else {
assert objectArray == null;
assert primitiveArray == null;
assert size == 0;
if (e instanceof Long l) {
var arr = new long[initialCapacity];
arr[0] = l;
primitiveArray = arr;
} else if (e instanceof Double d) {
var arr = new double[initialCapacity];
arr[0] = d;
primitiveArray = arr;
} else {
var arr = new Object[initialCapacity];
arr[0] = e;
objectArray = arr;
}
size = 1;
}
}
/** Obtains an element from the builder */
public Object get(int index) {
if (objectArray != null) {
return objectArray[index];
} else if (primitiveArray instanceof long[] longArray) {
return longArray[index];
} else if (primitiveArray instanceof double[] doubleArray) {
return doubleArray[index];
} else {
throw new ArrayIndexOutOfBoundsException();
}
}
/** A temporary workaround to be able to efficiently append an array to `ArrayList`. */
public void appendTo(List<T> list) {
for (T obj : list) {
add(obj);
}
}
/** Returns the current array of the builder. */
public Object toArray() {
if (objectArray != null) {
return objectArray.length == size ? objectArray : Arrays.copyOf(objectArray, size);
} else if (primitiveArray instanceof long[] longArray) {
return longArray.length == size ? longArray : Arrays.copyOf(longArray, size);
} else if (primitiveArray instanceof double[] doubleArray) {
return doubleArray.length == size ? doubleArray : Arrays.copyOf(doubleArray, size);
} else {
return EMPTY_ARRAY;
}
}
public int getSize() {
return size;
}
}

View File

@ -0,0 +1,16 @@
package org.enso.base;
public final class Array_Utils {
private Array_Utils() {}
/**
* This function forces the polyglot conversion of an Enso array into a `byte[]`. This allows for
* asserting that it is a valid `byte[]`.
*
* @param input the converted array.
* @return the `input` unchanged.
*/
public static byte[] ensureByteArray(byte[] input) {
return input;
}
}

View File

@ -788,6 +788,25 @@ type_spec name alter = Test.group name <|
Warning.limit_reached sorted . should_equal True
spec =
Test.group "Vector builder" <|
Test.specify "empty builder.get" <|
b = Vector.new_builder
e = Panic.catch Index_Out_Of_Bounds (b.at 0) err->
err.payload
Meta.type_of e . should_equal Index_Out_Of_Bounds
e.index . should_equal 0
e.length . should_equal 0
Test.specify "one number builder.get" <|
b = Vector.new_builder
b.append 32
e = Panic.catch Index_Out_Of_Bounds (b.at 1) err->
err.payload
Meta.type_of e . should_equal Index_Out_Of_Bounds
e.index . should_equal 1
e.length . should_equal 1
b.at 0 . should_equal 32
Test.group "Vector/Array equality" <|
v1 = [1, 2, 3]
a1 = v1.to_array

View File

@ -1,4 +1,6 @@
import project.Data.Vector.Vector
@Builtin_Type
type Array
at self index = @Builtin_Method "Array.at"
length self = @Builtin_Method "Array.length"
at self index = Vector.at self index
length self = Vector.length self

View File

@ -1,4 +1,10 @@
@Builtin_Type
type Vector a
from_array array = @Builtin_Method "Vector.from_array"
at self index = @Builtin_Method "Vector.at"
at self index = array_like_at self index
length self = array_like_length self
to_array self = array_like_vector_to_array self
array_like_at array index = @Builtin_Method "Array_Like_Helpers.at"
array_like_length array = @Builtin_Method "Array_Like_Helpers.length"
array_like_vector_to_array array = @Builtin_Method "Array_Like_Helpers.vector_to_array"