Implement hasLanguage interop message for all enso objects (#11538)

* EnsoObject is an abstract class, not an interface.

- Also, EnsoObject exports hasLanguage and getLanguage interop messages.
- BranchRecord converted to class

* Implement public getters in BranchResult

* Fix compilation of EnsoFile

* Add test that all enso values must have language

* Revert EnsoException - remove

* DataflowError and PanicException implement hasLanguage and getLanguage

* DataflowError is not EnsoObject - change signatures in some builtins

* Add more members to Module.isMemberInvocable.

Keep in sync with doInvoke.

* Revert "DataflowError and PanicException implement hasLanguage and getLanguage"

This reverts commit b30f3961b7.

* Update the test - test only non-primitive and non-exception values

* Fix indexes in CodeLocationsTest

* Add more members to Function.isMemberInvocable

Keep in sync with doInvoke.

* EnsoObject.toDisplayString delegates to toString method

* EnsoObject.toDisplayString is behind TruffleBoundary

* Warning exports InteropLibrary which delegates to value.

With the exception of toDisplayString message.

* WithWarnings needs to explicitly export toDisplayString.

It is not automatically delegated because it is implemented in the super type.

* EnsoObject.toDisplayString just throws AssertionError

* AssertionError is behind TruffleBoundary

* Implement toDisplayString on some truffle objects

* Warning exports WarningsLibrary

* Revert "Warning exports WarningsLibrary"

This reverts commit a06c672db5.

* Add some warnings test

* Warning.isNull is always false

Even if it wraps Nothing

* Add some unnecessary methods to fix the compilation

* EnsoObject.toDisplayString is abstract

* ImportExportScope.toDisplayString is behind TruffleBoundary.

This fixes native-image build of engine-runner.

* Hide some toDisplayString methods behind TruffleBoundary

This fixes native-image build of engine-runner.
Bypassing failing test.
This commit is contained in:
Pavel Marek 2024-11-20 14:23:33 +01:00 committed by GitHub
parent 2ae1c904ef
commit 04075c5ed7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
50 changed files with 552 additions and 175 deletions

View File

@ -9,12 +9,14 @@ import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import com.oracle.truffle.api.interop.InteropLibrary;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.URI;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.function.Predicate;
import org.enso.common.MethodNames;
import org.enso.interpreter.runtime.data.Type;
import org.enso.interpreter.runtime.type.ConstantsGen;
@ -272,6 +274,33 @@ main = Nothing
}
}
/**
* Primitive values and exceptions currently don't have an associated language.
*
* <p>TODO[PM]: Will be implemented in https://github.com/enso-org/enso/pull/11468
*/
@Test
public void allEnsoNonPrimitiveValuesHaveLanguage() throws Exception {
var gen = ValuesGenerator.create(ctx, Language.ENSO);
Predicate<Value> isPrimitiveOrException =
(val) -> val.fitsInInt() || val.fitsInDouble() || val.isBoolean() || val.isException();
var nonPrimitiveValues =
gen.allValues().stream().filter(isPrimitiveOrException.negate()).toList();
var interop = InteropLibrary.getUncached();
ContextUtils.executeInContext(
ctx,
() -> {
for (var value : nonPrimitiveValues) {
var unwrappedValue = ContextUtils.unwrapValue(ctx, value);
assertThat(
"Value " + unwrappedValue + " should have associated language",
interop.hasLanguage(unwrappedValue),
is(true));
}
return null;
});
}
@Test
public void compareQualifiedAndSimpleTypeName() throws Exception {
var g = generator();

View File

@ -2,16 +2,28 @@ package org.enso.interpreter.test;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.sameInstance;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import com.oracle.truffle.api.interop.InteropLibrary;
import java.util.List;
import org.enso.common.LanguageInfo;
import org.enso.common.MethodNames;
import org.enso.interpreter.node.expression.builtin.interop.syntax.HostValueToEnsoNode;
import org.enso.interpreter.runtime.EnsoContext;
import org.enso.interpreter.runtime.data.hash.EnsoHashMap;
import org.enso.interpreter.runtime.data.hash.HashMapGetNode;
import org.enso.interpreter.runtime.data.hash.HashMapInsertNode;
import org.enso.interpreter.runtime.data.hash.HashMapSizeNode;
import org.enso.interpreter.runtime.data.text.Text;
import org.enso.interpreter.runtime.data.vector.ArrayLikeHelpers;
import org.enso.interpreter.runtime.warning.AppendWarningNode;
import org.enso.interpreter.runtime.warning.Warning;
import org.enso.interpreter.runtime.warning.WarningsLibrary;
import org.enso.interpreter.runtime.warning.WithWarnings;
import org.enso.test.utils.ContextUtils;
import org.graalvm.polyglot.Context;
@ -194,4 +206,92 @@ public class WarningsTest {
assertEquals(
"Standard.Base.Error.Error", errorWithWarning.getMetaObject().getMetaQualifiedName());
}
@Test
public void warningsArray_readViaInterop_shouldNotRemoveWarnings() {
ContextUtils.executeInContext(
ctx,
() -> {
var warn1 = Warning.create(ensoContext, 1L, null);
var warn2 = Warning.create(ensoContext, 2L, null);
var arr = ArrayLikeHelpers.wrapEnsoObjects(warn1, warn2);
var interop = InteropLibrary.getUncached();
var warn1FromArr = interop.readArrayElement(arr, 0);
assertThat(
"warn1 and warn1FromArr should be the same reference",
warn1,
is(sameInstance(warn1FromArr)));
var warn2FromArr = interop.readArrayElement(arr, 1);
assertThat(
"warn2 and warn2FromArr should be the same reference",
warn2,
is(sameInstance(warn2FromArr)));
return null;
});
}
@Test
public void warningsArray_collectWarningsViaWarningsLibrary() {
ContextUtils.executeInContext(
ctx,
() -> {
var appendWarnNode = AppendWarningNode.getUncached();
var warnsLib = WarningsLibrary.getUncached();
var hashMapSizeNode = HashMapSizeNode.getUncached();
var hashMapGetNode = HashMapGetNode.getUncached();
var warn1 = Warning.create(ensoContext, 1L, null);
var warn2 = Warning.create(ensoContext, 2L, null);
var warnsMap = createWarningsMap(List.of(warn1, warn2));
var text1 = Text.create("1");
var text2 = Text.create("2");
var arr = ArrayLikeHelpers.wrapEnsoObjects(text1, text2);
var arrWithWarns = appendWarnNode.executeAppend(null, arr, warnsMap);
assertThat(warnsLib.hasWarnings(arrWithWarns), is(true));
var gatheredWarns = warnsLib.getWarnings(arrWithWarns, false);
assertThat("Hash size should be 2", hashMapSizeNode.execute(gatheredWarns), is(2L));
var warn1FromMap =
hashMapGetNode.execute(null, null, gatheredWarns, warn1.getSequenceId(), null);
assertThat(
"Original warning and warning gathered via WarningsLibrary should be the same object",
warn1 == warn1FromMap,
is(true));
return null;
});
}
@Test
public void nothingWithWarn_IsNotRemovedByHostValueToEnsoNode() {
ContextUtils.executeInContext(
ctx,
() -> {
var hostValueToEnsoNode = HostValueToEnsoNode.getUncached();
var warn = Warning.create(ensoContext, ensoContext.getNothing(), null);
var converted = hostValueToEnsoNode.execute(warn);
assertThat(converted, is(sameInstance(warn)));
return null;
});
}
@Test
public void nothingWithWarn_FromMapToArray() {
ContextUtils.executeInContext(
ctx,
() -> {
var warn = Warning.create(ensoContext, ensoContext.getNothing(), null);
var warnsMap = createWarningsMap(List.of(warn));
var warns = Warning.fromMapToArray(warnsMap);
assertThat(warns.length, is(1));
return null;
});
}
private EnsoHashMap createWarningsMap(List<Warning> warns) {
var map = EnsoHashMap.empty();
var mapInsertNode = HashMapInsertNode.getUncached();
for (var warn : warns) {
map = mapInsertNode.execute(null, map, warn.getSequenceId(), warn);
}
return map;
}
}

View File

@ -34,19 +34,25 @@ class CodeLocationsTest extends InterpreterTest {
"be correct in simple arithmetic expressions" in
withLocationsInstrumenter { instrumenter =>
val code = "main = 2 + 45 * 20"
instrumenter.assertNodeExists(7, 11, classOf[ApplicationNode])
instrumenter.assertNodeExists(11, 7, classOf[ApplicationNode])
instrumenter.assertNodeExists(11, 2, classOf[LiteralNode])
val code =
"""from Standard.Base.Data.Numbers import all
|main = (2 + 45) * 20
|""".stripMargin.replace("\r", "")
instrumenter.assertNodeExists(50, 13, classOf[ApplicationNode])
instrumenter.assertNodeExists(51, 6, classOf[ApplicationNode])
instrumenter.assertNodeExists(51, 1, classOf[LiteralNode])
eval(code)
()
}
"be correct with parenthesized expressions" in
withLocationsInstrumenter { instrumenter =>
val code = "main = (2 + 45) * 20"
instrumenter.assertNodeExists(7, 13, classOf[ApplicationNode])
instrumenter.assertNodeExists(8, 6, classOf[ApplicationNode])
val code =
"""from Standard.Base.Data.Numbers import all
|main = (2 + 45) * 20
|""".stripMargin.replace("\r", "")
instrumenter.assertNodeExists(50, 13, classOf[ApplicationNode])
instrumenter.assertNodeExists(51, 6, classOf[ApplicationNode])
eval(code)
()
}
@ -54,13 +60,12 @@ class CodeLocationsTest extends InterpreterTest {
"be correct in applications and method calls" in
withLocationsInstrumenter { instrumenter =>
val code =
"""import Standard.Base.Data.List.List
|import Standard.Base.Any.Any
"""from Standard.Base import all
|
|main = (2-2 == 0).if_then_else (List.Cons 5 6) 0
|""".stripMargin.linesIterator.mkString("\n")
instrumenter.assertNodeExists(73, 41, classOf[ApplicationNode])
instrumenter.assertNodeExists(98, 13, classOf[ApplicationNode])
instrumenter.assertNodeExists(38, 41, classOf[ApplicationNode])
instrumenter.assertNodeExists(63, 13, classOf[ApplicationNode])
eval(code)
()
}
@ -69,18 +74,18 @@ class CodeLocationsTest extends InterpreterTest {
withLocationsInstrumenter { instrumenter =>
val code =
"""
|import Standard.Base.IO
|from Standard.Base import all
|
|main =
| x = 2 + 2 * 2
| y = x * x
| IO.println y
|""".stripMargin.linesIterator.mkString("\n")
instrumenter.assertNodeExists(37, 13, classOf[AssignmentNode])
instrumenter.assertNodeExists(55, 9, classOf[AssignmentNode])
instrumenter.assertNodeExists(59, 1, classOf[ReadLocalVariableNode])
instrumenter.assertNodeExists(63, 1, classOf[ReadLocalVariableNode])
instrumenter.assertNodeExists(80, 1, classOf[ReadLocalVariableNode])
instrumenter.assertNodeExists(43, 13, classOf[AssignmentNode])
instrumenter.assertNodeExists(61, 9, classOf[AssignmentNode])
instrumenter.assertNodeExists(65, 1, classOf[ReadLocalVariableNode])
instrumenter.assertNodeExists(69, 1, classOf[ReadLocalVariableNode])
instrumenter.assertNodeExists(86, 1, classOf[ReadLocalVariableNode])
eval(code)
()
}
@ -89,8 +94,7 @@ class CodeLocationsTest extends InterpreterTest {
withLocationsInstrumenter { instrumenter =>
val code =
"""
|import Standard.Base.Nothing
|import Standard.Base.IO
|from Standard.Base import all
|
|Nothing.method =
| foo = a -> b ->
@ -102,10 +106,10 @@ class CodeLocationsTest extends InterpreterTest {
|main = Nothing.method
|""".stripMargin.linesIterator.mkString("\n")
instrumenter.assertNodeExists(137, 5, classOf[ApplicationNode])
instrumenter.assertNodeExists(155, 1, classOf[ReadLocalVariableNode])
instrumenter.assertNodeExists(151, 7, classOf[ApplicationNode])
instrumenter.assertNodeExists(163, 9, classOf[ApplicationNode])
instrumenter.assertNodeExists(114, 5, classOf[ApplicationNode])
instrumenter.assertNodeExists(132, 1, classOf[ReadLocalVariableNode])
instrumenter.assertNodeExists(128, 7, classOf[ApplicationNode])
instrumenter.assertNodeExists(140, 9, classOf[ApplicationNode])
eval(code)
()
}
@ -114,7 +118,7 @@ class CodeLocationsTest extends InterpreterTest {
withLocationsInstrumenter { instrumenter =>
val code =
"""
|import Standard.Base.Data.List.List
|from Standard.Base import all
|
|main =
| x = List.Cons 1 2
@ -131,10 +135,10 @@ class CodeLocationsTest extends InterpreterTest {
|
| foo x + foo y
|""".stripMargin.linesIterator.mkString("\n")
instrumenter.assertNodeExists(127, 0, 114, 1, classOf[CaseNode])
instrumenter.assertNodeExists(178, 7, classOf[ApplicationNode])
instrumenter.assertNodeExists(198, 9, classOf[AssignmentNode])
instrumenter.assertNodeExists(235, 5, classOf[ApplicationNode])
instrumenter.assertNodeExists(121, 0, 114, 1, classOf[CaseNode])
instrumenter.assertNodeExists(172, 7, classOf[ApplicationNode])
instrumenter.assertNodeExists(192, 9, classOf[AssignmentNode])
instrumenter.assertNodeExists(229, 5, classOf[ApplicationNode])
eval(code)
()
}
@ -142,7 +146,8 @@ class CodeLocationsTest extends InterpreterTest {
"be correct for lambdas" in
withLocationsInstrumenter { instrumenter =>
val code =
"""
"""from Standard.Base import all
|
|main =
| f = a -> b -> a + b
| g = x -> y ->
@ -151,8 +156,8 @@ class CodeLocationsTest extends InterpreterTest {
|
| f 1 (g 2 3)
|""".stripMargin.linesIterator.mkString("\n")
instrumenter.assertNodeExists(16, 15, classOf[CreateFunctionNode])
instrumenter.assertNodeExists(40, 42, classOf[CreateFunctionNode])
instrumenter.assertNodeExists(46, 15, classOf[CreateFunctionNode])
instrumenter.assertNodeExists(70, 42, classOf[CreateFunctionNode])
eval(code)
()
}
@ -160,16 +165,17 @@ class CodeLocationsTest extends InterpreterTest {
"be correct for defaulted arguments" in
withLocationsInstrumenter { instrumenter =>
val code =
"""
"""from Standard.Base import all
|
|main =
| bar = x -> x + x * x
| foo = x -> (y = bar x) -> x + y
| foo 0
|""".stripMargin.linesIterator.mkString("\n")
instrumenter.assertNodeExists(53, 5, classOf[ApplicationNode])
instrumenter.assertNodeExists(53, 3, classOf[ReadLocalVariableNode])
instrumenter.assertNodeExists(57, 1, classOf[ReadLocalVariableNode])
instrumenter.assertNodeExists(93, 5, classOf[ApplicationNode])
instrumenter.assertNodeExists(93, 1, classOf[ReadLocalVariableNode])
instrumenter.assertNodeExists(97, 1, classOf[ReadLocalVariableNode])
eval(code)
()
}
@ -177,13 +183,14 @@ class CodeLocationsTest extends InterpreterTest {
"be correct for lazy arguments" in
withLocationsInstrumenter { instrumenter =>
val code =
"""
"""from Standard.Base import all
|
|main =
| bar = a -> ~b -> ~c -> b
|
| bar 0 10 0
|""".stripMargin.linesIterator.mkString("\n")
instrumenter.assertNodeExists(35, 1, classOf[ForceNode])
instrumenter.assertNodeExists(65, 1, classOf[ForceNode])
eval(code)
()
}
@ -198,19 +205,21 @@ class CodeLocationsTest extends InterpreterTest {
"be correct for negated expressions" in
withLocationsInstrumenter { instrumenter =>
val code =
"""
"""from Standard.Base import all
|
|main =
| f = 1
| -f
|""".stripMargin.linesIterator.mkString("\n")
instrumenter.assertNodeExists(22, 1, 2, 1, classOf[ApplicationNode])
instrumenter.assertNodeExists(52, 1, 2, 1, classOf[ApplicationNode])
eval(code)
}
"be correct in sugared method definitions" in
withLocationsInstrumenter { instrumenter =>
val code =
"""
"""from Standard.Base.Data.Numbers import all
|
|Test.foo a b = a * b - a
|
|main = Test.foo 2 3
@ -221,7 +230,10 @@ class CodeLocationsTest extends InterpreterTest {
val method = mod.getMethod(tpe, "foo").get
method.value.invokeMember(
MethodNames.Function.GET_SOURCE_START
) shouldEqual 1
) should (
equal(44) or
equal(45)
)
method.value.invokeMember(
MethodNames.Function.GET_SOURCE_LENGTH
) should (
@ -229,7 +241,7 @@ class CodeLocationsTest extends InterpreterTest {
equal(25)
)
instrumenter.assertNodeExists(16, 9, classOf[ApplicationNode])
instrumenter.assertNodeExists(59, 9, classOf[ApplicationNode])
eval(code)
}
@ -237,20 +249,23 @@ class CodeLocationsTest extends InterpreterTest {
"be correct in sugared function definitions" in
withLocationsInstrumenter { instrumenter =>
val code =
"""|main =
"""|from Standard.Base import all
|
|main =
| f a b = a - b
| f 10 20
|""".stripMargin.linesIterator.mkString("\n")
instrumenter.assertNodeExists(11, 1, 13, 0, classOf[AssignmentNode])
instrumenter.assertNodeExists(19, 1, 5, 0, classOf[ApplicationNode])
instrumenter.assertNodeExists(41, 1, 13, 0, classOf[AssignmentNode])
instrumenter.assertNodeExists(49, 1, 5, 0, classOf[ApplicationNode])
eval(code)
}
"be correct in the presence of comments" in
withLocationsInstrumenter { instrumenter =>
val code =
"""
"""from Standard.Base import all
|
|# this is a comment
|#this too
|## But this is a doc.
@ -260,8 +275,8 @@ class CodeLocationsTest extends InterpreterTest {
| # perform the addition
| x + y # the addition is performed here
|""".stripMargin.linesIterator.mkString("\n")
instrumenter.assertNodeExists(82, 1, classOf[LiteralNode])
instrumenter.assertNodeExists(164, 5, classOf[ApplicationNode])
instrumenter.assertNodeExists(112, 1, classOf[LiteralNode])
instrumenter.assertNodeExists(194, 5, classOf[ApplicationNode])
eval(code) shouldEqual 3
}

View File

@ -1,6 +1,7 @@
package org.enso.interpreter.node.callable;
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.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame;
@ -56,7 +57,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 EnsoObject {
public static final class FunctionCall extends EnsoObject {
private final Function function;
private final State state;
private final @CompilerDirectives.CompilationFinal(dimensions = 1) Object[] arguments;
@ -132,7 +133,7 @@ public class FunctionCallInstrumentationNode extends Node implements Instrumenta
}
@Override
@CompilerDirectives.TruffleBoundary
@TruffleBoundary
public String toString() {
return "FunctionCall[function="
+ function
@ -140,6 +141,13 @@ public class FunctionCallInstrumentationNode extends Node implements Instrumenta
+ Arrays.toString(arguments)
+ "]";
}
@Override
@ExportMessage
@TruffleBoundary
public Object toDisplayString(boolean allowSideEffects) {
return toString();
}
}
/**

View File

@ -1,10 +1,27 @@
package org.enso.interpreter.node.controlflow.caseexpr;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.nodes.Node;
import org.enso.interpreter.runtime.EnsoContext;
import org.enso.interpreter.runtime.data.EnsoObject;
record BranchResult(boolean isMatched, Object result) implements EnsoObject {
final class BranchResult extends EnsoObject {
private final boolean isMatched;
private final Object result;
BranchResult(boolean isMatched, Object result) {
this.isMatched = isMatched;
this.result = result;
}
public boolean isMatched() {
return isMatched;
}
public Object result() {
return result;
}
static BranchResult failure(Node node) {
return new BranchResult(false, EnsoContext.get(node).getBuiltins().nothing());
}
@ -12,4 +29,10 @@ record BranchResult(boolean isMatched, Object result) implements EnsoObject {
static BranchResult success(Object result) {
return new BranchResult(true, result);
}
@Override
@TruffleBoundary
public Object toDisplayString(boolean allowSideEffects) {
return "BranchResult(" + isMatched + ")";
}
}

View File

@ -73,7 +73,7 @@ public abstract class AtomWithAHoleNode extends Node {
}
@ExportLibrary(InteropLibrary.class)
static final class HoleInAtom implements EnsoObject {
static final class HoleInAtom extends EnsoObject {
Atom result;
int index;
Function function;
@ -140,7 +140,8 @@ public abstract class AtomWithAHoleNode extends Node {
}
@ExportMessage
String toDisplayString(boolean pure) {
@Override
public String toDisplayString(boolean pure) {
return "Meta.atom_with_hole";
}
}

View File

@ -1,6 +1,7 @@
package org.enso.interpreter.node.expression.builtin.meta;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.RootCallTarget;
import com.oracle.truffle.api.instrumentation.EventBinding;
import com.oracle.truffle.api.interop.InteropException;
@ -14,7 +15,7 @@ import org.enso.interpreter.runtime.data.vector.ArrayLikeHelpers;
import org.enso.interpreter.runtime.instrument.Timer;
import org.enso.polyglot.debugger.IdExecutionService;
final class Instrumentor implements EnsoObject, IdExecutionService.Callbacks {
final class Instrumentor extends EnsoObject implements IdExecutionService.Callbacks {
private final IdExecutionService service;
private final RootCallTarget target;
@ -125,4 +126,16 @@ final class Instrumentor implements EnsoObject, IdExecutionService.Callbacks {
public Object getExecutionEnvironment(IdExecutionService.Info info) {
return null;
}
@Override
@TruffleBoundary
public Object toDisplayString(boolean allowSideEffects) {
String rootName;
if (target.getRootNode() != null) {
rootName = target.getRootNode().getQualifiedName();
} else {
rootName = "<unknown>";
}
return "Instrumentor(target = " + rootName + ")";
}
}

View File

@ -1,6 +1,7 @@
package org.enso.interpreter.runtime;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.TruffleFile;
import com.oracle.truffle.api.TruffleLogger;
import com.oracle.truffle.api.dsl.Cached;
@ -53,7 +54,7 @@ import org.enso.text.buffer.Rope;
/** Represents a source module with a known location. */
@ExportLibrary(InteropLibrary.class)
public final class Module implements EnsoObject {
public final class Module extends EnsoObject {
private ModuleSources sources;
private QualifiedName name;
private ModuleScope.Builder scopeBuilder;
@ -772,6 +773,10 @@ public final class Module implements EnsoObject {
boolean isMemberInvocable(String member) {
return member.equals(MethodNames.Module.GET_METHOD)
|| member.equals(MethodNames.Module.REPARSE)
|| member.equals(MethodNames.Module.GATHER_IMPORT_STATEMENTS)
|| member.equals(MethodNames.Module.GENERATE_DOCS)
|| member.equals(MethodNames.Module.GET_NAME)
|| member.equals(MethodNames.Module.GET_TYPE)
|| member.equals(MethodNames.Module.SET_SOURCE)
|| member.equals(MethodNames.Module.SET_SOURCE_FILE)
|| member.equals(MethodNames.Module.GET_ASSOCIATED_TYPE)
@ -795,8 +800,15 @@ public final class Module implements EnsoObject {
MethodNames.Module.EVAL_EXPRESSION);
}
@ExportMessage
@TruffleBoundary
@Override
public String toString() {
public String toDisplayString(boolean allowSideEffects) {
return "Module[" + name + ']';
}
@Override
public String toString() {
return toDisplayString(false);
}
}

View File

@ -1,6 +1,7 @@
package org.enso.interpreter.runtime.callable;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.dsl.Bind;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.Specialization;
@ -48,7 +49,7 @@ import org.enso.interpreter.runtime.state.State;
*/
@ExportLibrary(InteropLibrary.class)
@ExportLibrary(TypesLibrary.class)
public final class UnresolvedConstructor implements EnsoObject {
public final class UnresolvedConstructor extends EnsoObject {
private static final CallArgumentInfo[] NONE = new CallArgumentInfo[0];
private final String name;
private final Node where;
@ -75,13 +76,15 @@ public final class UnresolvedConstructor implements EnsoObject {
}
@Override
@CompilerDirectives.TruffleBoundary
@TruffleBoundary
public String toString() {
return ".." + name;
}
@ExportMessage
String toDisplayString(boolean allowSideEffects) {
@Override
@TruffleBoundary
public String toDisplayString(boolean allowSideEffects) {
return toString();
}

View File

@ -22,7 +22,7 @@ import org.enso.interpreter.runtime.scope.ModuleScope;
/** Simple runtime value representing a yet-unresolved by-name symbol. */
@ExportLibrary(InteropLibrary.class)
@ExportLibrary(TypesLibrary.class)
public final class UnresolvedConversion implements EnsoObject {
public final class UnresolvedConversion extends EnsoObject {
private final ModuleScope scope;
/**
@ -71,7 +71,8 @@ public final class UnresolvedConversion implements EnsoObject {
}
@ExportMessage
String toDisplayString(boolean allowSideEffects) {
@Override
public String toDisplayString(boolean allowSideEffects) {
return this.toString();
}

View File

@ -24,7 +24,7 @@ import org.graalvm.collections.Pair;
/** Simple runtime value representing a yet-unresolved by-name symbol. */
@ExportLibrary(InteropLibrary.class)
@ExportLibrary(TypesLibrary.class)
public final class UnresolvedSymbol implements EnsoObject {
public final class UnresolvedSymbol extends EnsoObject {
private final String name;
private final ModuleScope scope;
@ -85,7 +85,8 @@ public final class UnresolvedSymbol implements EnsoObject {
@ExportMessage
@TruffleBoundary
String toDisplayString(boolean allowSideEffects) {
@Override
public String toDisplayString(boolean allowSideEffects) {
return this.toString();
}

View File

@ -39,7 +39,7 @@ import org.slf4j.LoggerFactory;
/** A runtime representation of a function object in Enso. */
@ExportLibrary(InteropLibrary.class)
@ExportLibrary(TypesLibrary.class)
public final class Function implements EnsoObject {
public final class Function extends EnsoObject {
private final RootCallTarget callTarget;
private final MaterializedFrame scope;
private final FunctionSchema schema;
@ -276,7 +276,9 @@ public final class Function implements EnsoObject {
*/
@ExportMessage
boolean isMemberInvocable(String member) {
return member.equals(MethodNames.Function.EQUALS);
return member.equals(MethodNames.Function.EQUALS)
|| member.equals(MethodNames.Function.GET_SOURCE_START)
|| member.equals(MethodNames.Function.GET_SOURCE_LENGTH);
}
/**
@ -299,7 +301,10 @@ public final class Function implements EnsoObject {
*/
@ExportMessage
Object getMembers(boolean includeInternal) {
return ArrayLikeHelpers.wrapStrings(MethodNames.Function.EQUALS);
return ArrayLikeHelpers.wrapStrings(
MethodNames.Function.EQUALS,
MethodNames.Function.GET_SOURCE_START,
MethodNames.Function.GET_SOURCE_LENGTH);
}
/**
@ -428,7 +433,8 @@ public final class Function implements EnsoObject {
}
@ExportMessage
String toDisplayString(boolean sideEffects) {
@Override
public String toDisplayString(boolean sideEffects) {
return toString();
}

View File

@ -18,7 +18,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 EnsoObject {
public final class EnsoDate extends EnsoObject {
private final LocalDate date;
public EnsoDate(LocalDate date) {
@ -99,6 +99,7 @@ public final class EnsoDate implements EnsoObject {
@CompilerDirectives.TruffleBoundary
@ExportMessage
@Override
public Object toDisplayString(boolean allowSideEffects) {
return Core_Date_Utils.defaultLocalDateFormatter.format(date);
}

View File

@ -25,7 +25,7 @@ import org.enso.polyglot.common_utils.Core_Date_Utils;
pkg = "date",
name = "DateTime",
stdlibName = "Standard.Base.Data.Time.Date_Time.Date_Time")
public final class EnsoDateTime implements EnsoObject {
public final class EnsoDateTime extends EnsoObject {
private final ZonedDateTime dateTime;
public EnsoDateTime(ZonedDateTime dateTime) {
@ -227,6 +227,7 @@ public final class EnsoDateTime implements EnsoObject {
@ExportMessage
@CompilerDirectives.TruffleBoundary
@Override
public Object toDisplayString(boolean allowSideEffects) {
return Core_Date_Utils.defaultZonedDateTimeFormatter.format(dateTime);
}

View File

@ -22,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 EnsoObject {
public final class EnsoDuration extends EnsoObject {
private final Duration duration;
public EnsoDuration(Duration duration) {
@ -185,6 +185,7 @@ public final class EnsoDuration implements EnsoObject {
@ExportMessage
@TruffleBoundary
@Override
public String toDisplayString(boolean allowSideEffects) {
return duration.toString();
}

View File

@ -53,7 +53,7 @@ import org.enso.interpreter.runtime.library.dispatch.TypesLibrary;
@ExportLibrary(InteropLibrary.class)
@ExportLibrary(TypesLibrary.class)
@Builtin(pkg = "io", name = "File", stdlibName = "Standard.Base.System.File.File")
public final class EnsoFile implements EnsoObject {
public final class EnsoFile extends EnsoObject {
private final TruffleFile truffleFile;
public EnsoFile(TruffleFile truffleFile) {
@ -79,7 +79,7 @@ public final class EnsoFile implements EnsoObject {
}
@ExportLibrary(InteropLibrary.class)
static final class EnsoOutputStream implements EnsoObject {
static final class EnsoOutputStream extends EnsoObject {
private static final String[] MEMBERS = new String[] {"write", "flush", "close"};
private final OutputStream os;
@ -182,6 +182,12 @@ public final class EnsoFile implements EnsoObject {
public String toString() {
return "EnsoOutputStream";
}
@Override
@ExportMessage
public Object toDisplayString(boolean allowSideEffects) {
return toString();
}
}
@Builtin.Method(name = "input_stream_builtin")
@ -200,7 +206,7 @@ public final class EnsoFile implements EnsoObject {
}
@ExportLibrary(InteropLibrary.class)
static final class EnsoInputStream implements EnsoObject {
static final class EnsoInputStream extends EnsoObject {
private static final String[] MEMBERS =
new String[] {
"read", "readAllBytes", "readNBytes", "skipNBytes", "markSupported", "available", "close"
@ -227,6 +233,12 @@ public final class EnsoFile implements EnsoObject {
return ArrayLikeHelpers.wrapStrings(MEMBERS);
}
@ExportMessage
@Override
public Object toDisplayString(boolean allowSideEffects) {
return "EnsoInputStream";
}
@TruffleBoundary(allowInlining = true)
private int read() throws IOException {
return delegate.read();
@ -734,7 +746,8 @@ public final class EnsoFile implements EnsoObject {
autoRegister = false)
@Builtin.Specialize
@TruffleBoundary
public static EnsoObject fromString(EnsoContext context, String path)
@SuppressWarnings("generic-enso-builtin-type")
public static Object fromString(EnsoContext context, String path)
throws IllegalArgumentException {
try {
TruffleFile file = context.getPublicTruffleFile(path);
@ -766,14 +779,22 @@ public final class EnsoFile implements EnsoObject {
autoRegister = false)
@Builtin.Specialize
@TruffleBoundary
public static EnsoObject userHome(EnsoContext context) {
@SuppressWarnings("generic-enso-builtin-type")
public static Object userHome(EnsoContext context) {
return fromString(context, System.getProperty("user.home"));
}
@ExportMessage
@TruffleBoundary
@Override
public String toDisplayString(boolean allowSideEffects) {
return "(File " + truffleFile.getPath() + ")";
}
@Override
@TruffleBoundary
public String toString() {
return "(File " + truffleFile.getPath() + ")";
return toDisplayString(false);
}
@ExportMessage

View File

@ -35,7 +35,7 @@ import org.graalvm.collections.Pair;
@ExportLibrary(TypesLibrary.class)
@ExportLibrary(InteropLibrary.class)
public final class EnsoMultiValue implements EnsoObject {
public final class EnsoMultiValue extends EnsoObject {
@CompilationFinal(dimensions = 1)
private final Type[] types;
@ -73,7 +73,9 @@ public final class EnsoMultiValue implements EnsoObject {
}
@ExportMessage
String toDisplayString(boolean ignore) {
@TruffleBoundary
@Override
public String toDisplayString(boolean ignore) {
return toString();
}

View File

@ -1,6 +1,29 @@
package org.enso.interpreter.runtime.data;
import com.oracle.truffle.api.TruffleLanguage;
import com.oracle.truffle.api.interop.InteropLibrary;
import com.oracle.truffle.api.interop.TruffleObject;
import com.oracle.truffle.api.library.ExportLibrary;
import com.oracle.truffle.api.library.ExportMessage;
import org.enso.interpreter.EnsoLanguage;
/** All non-primitive Enso types extends from {@code EnsoObject}. */
public interface EnsoObject extends TruffleObject {}
@ExportLibrary(InteropLibrary.class)
public abstract class EnsoObject implements TruffleObject {
@ExportMessage
public boolean hasLanguage() {
return true;
}
@ExportMessage
public Class<? extends TruffleLanguage<?>> getLanguage() {
return EnsoLanguage.class;
}
/**
* This abstract method needs to be declared here with the annotation {@code @ExportMessage} so
* that the Truffle DSL is satisfied.
*/
@ExportMessage
public abstract Object toDisplayString(boolean allowSideEffects);
}

View File

@ -12,7 +12,7 @@ import org.enso.interpreter.runtime.data.vector.ArrayLikeHelpers;
/** Wrapper for exposing sources to Enso. Delegates to original methods with no behavior changes. */
@ExportLibrary(InteropLibrary.class)
public final class EnsoSource implements EnsoObject {
public final class EnsoSource extends EnsoObject {
private static final String[] MEMBERS = {
"getLanguage", //
"getName", //
@ -69,4 +69,11 @@ public final class EnsoSource implements EnsoObject {
Object getMembers(boolean includeInternal) {
return ArrayLikeHelpers.wrapStrings(MEMBERS);
}
@Override
@TruffleBoundary
@ExportMessage
public Object toDisplayString(boolean allowSideEffects) {
return "EnsoSource{" + (source != null ? source.toString() : "") + "}";
}
}

View File

@ -15,7 +15,7 @@ import org.enso.interpreter.runtime.data.vector.ArrayLikeHelpers;
* changes.
*/
@ExportLibrary(InteropLibrary.class)
public final class EnsoSourceSection implements EnsoObject {
public final class EnsoSourceSection extends EnsoObject {
private static final String[] MEMBERS = {
"getStartLine", //
"getEndLine", //
@ -34,6 +34,7 @@ public final class EnsoSourceSection implements EnsoObject {
private final SourceSection sourceSection;
public EnsoSourceSection(SourceSection sourceSection) {
assert sourceSection != null;
this.sourceSection = sourceSection;
}
@ -78,4 +79,11 @@ public final class EnsoSourceSection implements EnsoObject {
Object getMembers(boolean includeInternal) {
return ArrayLikeHelpers.wrapStrings(MEMBERS);
}
@Override
@TruffleBoundary
@ExportMessage
public Object toDisplayString(boolean allowSideEffects) {
return "EnsoSourceSection{" + sourceSection + "}";
}
}

View File

@ -23,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 EnsoObject {
public final class EnsoTimeOfDay extends EnsoObject {
private final LocalTime localTime;
public EnsoTimeOfDay(LocalTime localTime) {
@ -165,6 +165,7 @@ public final class EnsoTimeOfDay implements EnsoObject {
@CompilerDirectives.TruffleBoundary
@ExportMessage
@Override
public Object toDisplayString(boolean allowSideEffects) {
return DateTimeFormatter.ISO_LOCAL_TIME.format(localTime);
}

View File

@ -1,6 +1,7 @@
package org.enso.interpreter.runtime.data;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.dsl.Bind;
import com.oracle.truffle.api.interop.InteropLibrary;
import com.oracle.truffle.api.interop.UnsupportedMessageException;
@ -23,7 +24,7 @@ import org.enso.polyglot.common_utils.Core_Date_Utils;
pkg = "date",
name = "TimeZone",
stdlibName = "Standard.Base.Data.Time.Time_Zone.Time_Zone")
public final class EnsoTimeZone implements EnsoObject {
public final class EnsoTimeZone extends EnsoObject {
private final ZoneId zone;
public EnsoTimeZone(ZoneId zone) {
@ -84,7 +85,9 @@ public final class EnsoTimeZone implements EnsoObject {
}
@ExportMessage
String toDisplayString(boolean ignoreSideEffects) {
@Override
@TruffleBoundary
public String toDisplayString(boolean ignoreSideEffects) {
return zone.toString();
}

View File

@ -1,5 +1,6 @@
package org.enso.interpreter.runtime.data;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.dsl.Bind;
import com.oracle.truffle.api.interop.InteropLibrary;
import com.oracle.truffle.api.library.ExportLibrary;
@ -15,7 +16,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 EnsoObject {
public final class ManagedResource extends EnsoObject {
private final Object resource;
private final PhantomReference<ManagedResource> phantomReference;
@ -93,4 +94,11 @@ public final class ManagedResource implements EnsoObject {
Type getType(@Bind("$node") Node node) {
return EnsoContext.get(node).getBuiltins().managedResource();
}
@ExportMessage
@TruffleBoundary
@Override
public String toDisplayString(boolean allowSideEffects) {
return resource.toString();
}
}

View File

@ -1,7 +1,9 @@
package org.enso.interpreter.runtime.data;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.dsl.Bind;
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;
import com.oracle.truffle.api.nodes.Node;
@ -13,7 +15,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 EnsoObject {
public final class Ref extends EnsoObject {
private volatile Object value;
/**
@ -68,4 +70,17 @@ public final class Ref implements EnsoObject {
Type getType(@Bind("$node") Node node) {
return EnsoContext.get(node).getBuiltins().ref();
}
@ExportMessage
Object toDisplayString(
boolean allowSideEffects, @CachedLibrary(limit = "3") InteropLibrary interop) {
return interop.toDisplayString(value, allowSideEffects);
}
@TruffleBoundary
@Override
@ExportMessage.Ignore
public Object toDisplayString(boolean allowSideEffects) {
return toDisplayString(allowSideEffects, InteropLibrary.getUncached());
}
}

View File

@ -30,7 +30,7 @@ import org.enso.pkg.QualifiedName;
@ExportLibrary(TypesLibrary.class)
@ExportLibrary(InteropLibrary.class)
public final class Type implements EnsoObject {
public final class Type extends EnsoObject {
private final String name;
private @CompilerDirectives.CompilationFinal ModuleScope.Builder definitionScope;
@ -279,7 +279,8 @@ public final class Type implements EnsoObject {
}
@ExportMessage
String toDisplayString(boolean allowSideEffects) {
@Override
public String toDisplayString(boolean allowSideEffects) {
return name;
}

View File

@ -19,7 +19,6 @@ import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;
import org.enso.interpreter.EnsoLanguage;
import org.enso.interpreter.runtime.callable.UnresolvedSymbol;
import org.enso.interpreter.runtime.callable.argument.ArgumentDefinition;
import org.enso.interpreter.runtime.callable.function.Function;
@ -51,7 +50,7 @@ import org.enso.interpreter.runtime.warning.WarningsLibrary;
*/
@ExportLibrary(InteropLibrary.class)
@ExportLibrary(TypesLibrary.class)
public abstract class Atom implements EnsoObject {
public abstract class Atom extends EnsoObject {
final AtomConstructor constructor;
private Integer hashCode;
@ -383,6 +382,18 @@ public abstract class Atom implements EnsoObject {
}
}
@Override
@TruffleBoundary
@ExportMessage.Ignore
public Object toDisplayString(boolean allowSideEffects) {
return toDisplayString(
allowSideEffects,
InteropLibrary.getUncached(),
WarningsLibrary.getUncached(),
InteropLibrary.getUncached(),
BranchProfile.getUncached());
}
@ExportMessage
Text toDisplayString(
boolean allowSideEffects,
@ -419,16 +430,6 @@ public abstract class Atom implements EnsoObject {
return Text.create(msg);
}
@ExportMessage
Class<EnsoLanguage> getLanguage() {
return EnsoLanguage.class;
}
@ExportMessage
boolean hasLanguage() {
return true;
}
@ExportMessage
boolean hasType() {
return true;

View File

@ -41,7 +41,7 @@ import org.enso.pkg.QualifiedName;
*/
@ExportLibrary(InteropLibrary.class)
@ExportLibrary(TypesLibrary.class)
public final class AtomConstructor implements EnsoObject {
public final class AtomConstructor extends EnsoObject {
private final String name;
private final Module definitionModule;
@ -414,7 +414,8 @@ public final class AtomConstructor implements EnsoObject {
@ExportMessage
@TruffleBoundary
String toDisplayString(boolean allowSideEffects) {
@Override
public String toDisplayString(boolean allowSideEffects) {
var sb = new StringBuilder();
sb.append("Constructor<").append(getDisplayName()).append(">");
for (var f : getFields()) {

View File

@ -1,15 +1,19 @@
package org.enso.interpreter.runtime.data.atom;
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.dsl.NodeFactory;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.interop.InteropLibrary;
import com.oracle.truffle.api.library.ExportLibrary;
import com.oracle.truffle.api.library.ExportMessage;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.profiles.BranchProfile;
import java.util.List;
import org.enso.interpreter.runtime.data.atom.UnboxingAtom.FieldGetterNode;
import org.enso.interpreter.runtime.data.atom.UnboxingAtom.FieldSetterNode;
import org.enso.interpreter.runtime.warning.WarningsLibrary;
/**
* A version of {@link org.enso.interpreter.runtime.data.atom.Atom} that stores its fields in an
@ -82,6 +86,17 @@ final class BoxingAtom extends Atom {
fields[index] = value;
}
@Override
@TruffleBoundary
public Object toDisplayString(boolean allowSideEffects) {
return toDisplayString(
allowSideEffects,
InteropLibrary.getUncached(),
WarningsLibrary.getUncached(),
InteropLibrary.getUncached(),
BranchProfile.getUncached());
}
private static class InstantiatorNode extends UnboxingAtom.InstantiatorNode {
@Override
public Atom execute(AtomConstructor constructor, Layout layout, Object[] args) {

View File

@ -36,7 +36,7 @@ import org.enso.interpreter.runtime.library.dispatch.TypesLibrary;
@ExportLibrary(TypesLibrary.class)
@ExportLibrary(InteropLibrary.class)
@Builtin(stdlibName = "Standard.Base.Data.Dictionary.Dictionary", name = "Dictionary")
public final class EnsoHashMap implements EnsoObject {
public final class EnsoHashMap extends EnsoObject {
private final EnsoHashMapBuilder mapBuilder;
private final int generation;
private final int size;
@ -166,7 +166,8 @@ public final class EnsoHashMap implements EnsoObject {
@ExportMessage
@TruffleBoundary
Object toDisplayString(boolean allowSideEffects) {
@Override
public Object toDisplayString(boolean allowSideEffects) {
return toString(true);
}

View File

@ -15,7 +15,7 @@ import org.enso.interpreter.runtime.data.vector.ArrayLikeHelpers;
* (array), and for Enso {@code Map.to_vector} method. May be empty.
*/
@ExportLibrary(InteropLibrary.class)
final class HashEntriesVector implements EnsoObject {
final class HashEntriesVector extends EnsoObject {
private final EnsoObject[] entryPairs;
private HashEntriesVector(Object[] keys, Object[] values) {
@ -73,8 +73,14 @@ final class HashEntriesVector implements EnsoObject {
throw UnsupportedMessageException.create();
}
@Override
@ExportMessage
public Object toDisplayString(boolean allowSideEffects) {
return "HashEntriesVector";
}
@ExportLibrary(InteropLibrary.class)
static final class EntryPair implements EnsoObject {
static final class EntryPair extends EnsoObject {
private final Object key;
private final Object value;
@ -126,7 +132,8 @@ final class HashEntriesVector implements EnsoObject {
@TruffleBoundary
@ExportMessage
Object toDisplayString(boolean sideEffectsAllowed) {
@Override
public String toDisplayString(boolean sideEffectsAllowed) {
return "(" + key + ", " + value + ")";
}
}

View File

@ -34,6 +34,10 @@ public abstract class HashMapGetNode extends Node {
return HashMapGetNodeGen.create();
}
public static HashMapGetNode getUncached() {
return HashMapGetNodeGen.getUncached();
}
public abstract Object execute(
VirtualFrame frame, State state, Object self, Object key, @Suspend Object defaultValue);

View File

@ -32,6 +32,10 @@ public abstract class HashMapInsertNode extends Node {
return HashMapInsertNodeGen.create();
}
public static HashMapInsertNode getUncached() {
return HashMapInsertNodeGen.getUncached();
}
public abstract EnsoHashMap execute(VirtualFrame frame, Object self, Object key, Object value);
@Specialization

View File

@ -25,7 +25,7 @@ import org.enso.polyglot.common_utils.Core_Text_Utils;
/** The main runtime type for Enso's Text. */
@ExportLibrary(InteropLibrary.class)
@ExportLibrary(TypesLibrary.class)
public final class Text implements EnsoObject {
public final class Text extends EnsoObject {
private static final Lock LOCK = new ReentrantLock();
private static final Text EMPTY = new Text("");
private volatile Object contents;
@ -197,6 +197,12 @@ public final class Text implements EnsoObject {
return Core_Text_Utils.computeGraphemeLength(toString());
}
@Override
@ExportMessage.Ignore
public Object toDisplayString(boolean allowSideEffects) {
return toDisplayString(allowSideEffects, ToJavaStringNode.getUncached());
}
@CompilerDirectives.TruffleBoundary
@ExportMessage
String toDisplayString(

View File

@ -1,6 +1,7 @@
package org.enso.interpreter.runtime.data.vector;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.dsl.Bind;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.Cached.Shared;
@ -32,7 +33,7 @@ import org.enso.interpreter.runtime.warning.WarningsLibrary;
@ExportLibrary(TypesLibrary.class)
@ExportLibrary(WarningsLibrary.class)
@Builtin(pkg = "mutable", stdlibName = "Standard.Base.Data.Array.Array")
final class Array implements EnsoObject {
final class Array extends EnsoObject {
private final Object[] items;
/** If true, some elements contain warning, and thus, this Array contains warning. */
@ -152,7 +153,9 @@ final class Array implements EnsoObject {
}
@ExportMessage
String toDisplayString(boolean b) {
@TruffleBoundary
@Override
public String toDisplayString(boolean b) {
return toString();
}

View File

@ -15,7 +15,7 @@ import org.enso.interpreter.runtime.data.EnsoObject;
import org.enso.interpreter.runtime.warning.WarningsLibrary;
@ExportLibrary(InteropLibrary.class)
final class ArrayBuilder implements EnsoObject {
final class ArrayBuilder extends EnsoObject {
private static final String[] MEMBERS =
new String[] {"isEmpty", "add", "appendTo", "get", "getSize", "toArray"};
private final int initialCapacity;
@ -238,7 +238,8 @@ final class ArrayBuilder implements EnsoObject {
}
@ExportMessage
String toDisplayString(boolean ignore) {
@Override
public String toDisplayString(boolean ignore) {
return "Array_Builder";
}

View File

@ -1,5 +1,6 @@
package org.enso.interpreter.runtime.data.vector;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.dsl.Bind;
import com.oracle.truffle.api.interop.InteropLibrary;
import com.oracle.truffle.api.interop.InvalidArrayIndexException;
@ -14,7 +15,7 @@ import org.enso.interpreter.runtime.library.dispatch.TypesLibrary;
@ExportLibrary(TypesLibrary.class)
@ExportLibrary(InteropLibrary.class)
final class ArrayOverBuffer implements EnsoObject {
final class ArrayOverBuffer extends EnsoObject {
private final ByteBuffer buffer;
private ArrayOverBuffer(ByteBuffer buffer) {
@ -61,7 +62,9 @@ final class ArrayOverBuffer implements EnsoObject {
}
@ExportMessage
String toDisplayString(boolean allowSideEffects) {
@TruffleBoundary
@Override
public String toDisplayString(boolean allowSideEffects) {
final InteropLibrary iop = InteropLibrary.getUncached();
return DisplayArrayUtils.toDisplayString(this, allowSideEffects, iop);
}

View File

@ -1,6 +1,7 @@
package org.enso.interpreter.runtime.data.vector;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.dsl.Bind;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.ImportStatic;
@ -28,7 +29,7 @@ import org.enso.interpreter.runtime.library.dispatch.TypesLibrary;
@ExportLibrary(InteropLibrary.class)
@ExportLibrary(TypesLibrary.class)
@ImportStatic(BranchProfile.class)
final class ArrayProxy implements EnsoObject {
final class ArrayProxy extends EnsoObject {
private final long length;
private final Object at;
@ -76,7 +77,9 @@ final class ArrayProxy implements EnsoObject {
}
@ExportMessage
String toDisplayString(boolean b) {
@TruffleBoundary
@Override
public String toDisplayString(boolean b) {
return toString();
}

View File

@ -1,6 +1,7 @@
package org.enso.interpreter.runtime.data.vector;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.dsl.Bind;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.Cached.Shared;
@ -23,7 +24,7 @@ import org.enso.interpreter.runtime.warning.WarningsLibrary;
@ExportLibrary(TypesLibrary.class)
@ExportLibrary(InteropLibrary.class)
@ExportLibrary(WarningsLibrary.class)
final class ArraySlice implements EnsoObject {
final class ArraySlice extends EnsoObject {
private final Object storage;
private final long start;
private final long end;
@ -184,4 +185,11 @@ final class ArraySlice implements EnsoObject {
var ctx = EnsoContext.get(node);
return ctx.getBuiltins().array();
}
@Override
@ExportMessage
@TruffleBoundary
public Object toDisplayString(boolean allowSideEffects) {
return "ArraySlice{" + start + ", " + end + "}";
}
}

View File

@ -23,7 +23,7 @@ import org.enso.interpreter.runtime.warning.WarningsLibrary;
@ExportLibrary(InteropLibrary.class)
@ExportLibrary(TypesLibrary.class)
@Builtin(pkg = "immutable", stdlibName = "Standard.Base.Data.Vector.Vector")
abstract class Vector implements EnsoObject {
abstract class Vector extends EnsoObject {
private static final Vector EMPTY_LONG = new Long(new long[0]);
private static final Vector EMPTY_DOUBLE = new Double(new double[0]);
private static final Vector EMPTY_VECTOR = new EnsoOnly(new Object[0]);
@ -72,7 +72,8 @@ abstract class Vector implements EnsoObject {
@ExportMessage
@CompilerDirectives.TruffleBoundary
String toDisplayString(boolean allowSideEffects) {
@Override
public String toDisplayString(boolean allowSideEffects) {
final InteropLibrary iop = InteropLibrary.getUncached();
return DisplayArrayUtils.toDisplayString(this, allowSideEffects, iop);
}

View File

@ -20,7 +20,6 @@ import org.enso.interpreter.node.callable.IndirectInvokeMethodNode;
import org.enso.interpreter.node.expression.builtin.text.util.TypeToDisplayTextNode;
import org.enso.interpreter.runtime.EnsoContext;
import org.enso.interpreter.runtime.callable.UnresolvedSymbol;
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;
@ -36,7 +35,7 @@ import org.enso.interpreter.runtime.state.State;
@ExportLibrary(InteropLibrary.class)
@ExportLibrary(TypesLibrary.class)
@ImportStatic(PanicException.class)
public final class DataflowError extends AbstractTruffleException implements EnsoObject {
public final class DataflowError extends AbstractTruffleException {
/** Signals (local) values that haven't yet been initialized */
public static final DataflowError UNINITIALIZED = new DataflowError(null, (Node) null);

View File

@ -21,7 +21,6 @@ import org.enso.interpreter.node.expression.builtin.text.util.TypeToDisplayTextN
import org.enso.interpreter.runtime.EnsoContext;
import org.enso.interpreter.runtime.callable.UnresolvedSymbol;
import org.enso.interpreter.runtime.callable.argument.CallArgumentInfo;
import org.enso.interpreter.runtime.data.EnsoObject;
import org.enso.interpreter.runtime.data.Type;
import org.enso.interpreter.runtime.data.atom.Atom;
import org.enso.interpreter.runtime.data.text.Text;
@ -33,7 +32,7 @@ import org.slf4j.LoggerFactory;
/** An exception type for user thrown panic exceptions. */
@ExportLibrary(value = InteropLibrary.class, delegateTo = "payload")
@ExportLibrary(TypesLibrary.class)
public final class PanicException extends AbstractTruffleException implements EnsoObject {
public final class PanicException extends AbstractTruffleException {
final Object payload;
private String cacheMessage;

View File

@ -4,7 +4,6 @@ import com.oracle.truffle.api.exception.AbstractTruffleException;
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.runtime.data.EnsoObject;
import org.enso.interpreter.runtime.library.dispatch.TypesLibrary;
/**
@ -14,7 +13,7 @@ import org.enso.interpreter.runtime.library.dispatch.TypesLibrary;
* not function in textual mode.
*/
@ExportLibrary(TypesLibrary.class)
public final class PanicSentinel extends AbstractTruffleException implements EnsoObject {
public final class PanicSentinel extends AbstractTruffleException {
final PanicException panic;
/**

View File

@ -17,7 +17,7 @@ import org.enso.interpreter.runtime.library.dispatch.TypesLibrary;
/** Internal wrapper for a {@link BigInteger}. */
@ExportLibrary(InteropLibrary.class)
@ExportLibrary(TypesLibrary.class)
public final class EnsoBigInteger implements EnsoObject {
public final class EnsoBigInteger extends EnsoObject {
private final BigInteger value;
/**
@ -45,7 +45,8 @@ public final class EnsoBigInteger implements EnsoObject {
@CompilerDirectives.TruffleBoundary
@ExportMessage
String toDisplayString(boolean allowSideEffects) {
@Override
public String toDisplayString(boolean allowSideEffects) {
return value.toString();
}

View File

@ -1,7 +1,6 @@
package org.enso.interpreter.runtime.scope;
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.UnknownIdentifierException;
@ -17,7 +16,6 @@ import java.util.Map;
import java.util.Map.Entry;
import java.util.stream.Collectors;
import org.enso.compiler.pass.analyse.FramePointer;
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;
@ -35,7 +33,7 @@ import org.enso.interpreter.runtime.error.DataflowError;
* </ul>
*/
@ExportLibrary(InteropLibrary.class)
public class DebugLocalScope implements EnsoObject {
public class DebugLocalScope extends EnsoObject {
private final EnsoRootNode rootNode;
/** All the bindings, including the parent scopes. */
@ -119,16 +117,6 @@ public class DebugLocalScope implements EnsoObject {
return bindingsByLevels;
}
@ExportMessage
boolean hasLanguage() {
return true;
}
@ExportMessage
Class<? extends TruffleLanguage<?>> getLanguage() {
return EnsoLanguage.class;
}
@ExportMessage
boolean isScope() {
return true;
@ -245,7 +233,8 @@ public class DebugLocalScope implements EnsoObject {
@ExportMessage
@TruffleBoundary
String toDisplayString(boolean allowSideEffects) {
@Override
public String toDisplayString(boolean allowSideEffects) {
return rootNode.toString();
}
@ -277,7 +266,7 @@ public class DebugLocalScope implements EnsoObject {
/** Simple interop wrapper for a list of strings. */
@ExportLibrary(InteropLibrary.class)
static final class ScopeMembers implements EnsoObject {
static final class ScopeMembers extends EnsoObject {
private final List<String> memberNames;
ScopeMembers(List<String> memberNames) {
@ -308,5 +297,12 @@ public class DebugLocalScope implements EnsoObject {
public String toString() {
return memberNames.toString();
}
@Override
@ExportMessage
@TruffleBoundary
public Object toDisplayString(boolean allowSideEffects) {
return toString();
}
}
}

View File

@ -1,5 +1,6 @@
package org.enso.interpreter.runtime.scope;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import java.util.List;
import org.enso.compiler.context.CompilerContext;
import org.enso.interpreter.runtime.Module;
@ -11,7 +12,7 @@ import org.enso.interpreter.runtime.data.Type;
* A proxy scope delegating to the underlying module's scope. Additionally, `ImportExportScope` may
* limit the number of types that are imported/exported.
*/
public class ImportExportScope implements EnsoObject {
public class ImportExportScope extends EnsoObject {
private final Module module;
private final List<String> typesOnlyNames;
@ -67,4 +68,10 @@ public class ImportExportScope implements EnsoObject {
return null;
}
}
@Override
@TruffleBoundary
public Object toDisplayString(boolean allowSideEffects) {
return "ImportExportScope{" + module.getName().toString() + "}";
}
}

View File

@ -1,6 +1,7 @@
package org.enso.interpreter.runtime.scope;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.interop.TruffleObject;
import com.oracle.truffle.api.library.ExportLibrary;
import com.oracle.truffle.api.library.ExportMessage;
@ -20,7 +21,7 @@ import org.enso.interpreter.runtime.util.CachingSupplier;
/** A representation of Enso's per-file top-level scope. */
@ExportLibrary(TypesLibrary.class)
public final class ModuleScope implements EnsoObject {
public final class ModuleScope extends EnsoObject {
private final Type associatedType;
private final Module module;
private final Map<String, Supplier<TruffleObject>> polyglotSymbols;
@ -290,6 +291,12 @@ public final class ModuleScope implements EnsoObject {
return "Scope" + module;
}
@Override
@TruffleBoundary
public Object toDisplayString(boolean allowSideEffects) {
return toString();
}
public static class Builder {
@CompilerDirectives.CompilationFinal private ModuleScope moduleScope = null;

View File

@ -17,7 +17,6 @@ import java.util.concurrent.ExecutionException;
import org.enso.common.MethodNames;
import org.enso.compiler.PackageRepository;
import org.enso.editions.LibraryName;
import org.enso.interpreter.EnsoLanguage;
import org.enso.interpreter.runtime.EnsoContext;
import org.enso.interpreter.runtime.Module;
import org.enso.interpreter.runtime.builtin.Builtins;
@ -30,7 +29,7 @@ import org.enso.pkg.QualifiedName;
/** Represents the top scope of Enso execution, containing all the importable modules. */
@ExportLibrary(InteropLibrary.class)
public final class TopLevelScope implements EnsoObject {
public final class TopLevelScope extends EnsoObject {
private final Builtins builtins;
private final PackageRepository packageRepository;
@ -263,26 +262,6 @@ public final class TopLevelScope implements EnsoObject {
throw UnsupportedMessageException.create();
}
/**
* Checks if this value is associated with a language.
*
* @return {@code true}
*/
@ExportMessage
final boolean hasLanguage() {
return true;
}
/**
* Returns the language associated with this scope value.
*
* @return the language with which this value is associated
*/
@ExportMessage
final Class<EnsoLanguage> getLanguage() {
return EnsoLanguage.class;
}
/**
* Converts this scope to a human readable string.
*
@ -290,7 +269,8 @@ public final class TopLevelScope implements EnsoObject {
* @return a string representation of this scope
*/
@ExportMessage
final Object toDisplayString(boolean allowSideEffects) {
@Override
public Object toDisplayString(boolean allowSideEffects) {
return "Enso.Top_Scope";
}
}

View File

@ -13,7 +13,6 @@ 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.runtime.EnsoContext;
import org.enso.interpreter.runtime.data.EnsoObject;
import org.enso.interpreter.runtime.data.hash.EnsoHashMap;
import org.enso.interpreter.runtime.data.hash.HashMapInsertAllNode;
import org.enso.interpreter.runtime.data.hash.HashMapInsertNode;
@ -42,7 +41,7 @@ public abstract class AppendWarningNode extends Node {
* It is expected that all the elements in the container are of {@link Warning} class.
* @return A wrapped object with warnings
*/
public abstract EnsoObject executeAppend(VirtualFrame frame, Object object, Object warnings);
public abstract Object executeAppend(VirtualFrame frame, Object object, Object warnings);
@Specialization(guards = "!isError(object)")
WithWarnings doSingleWarning(
@ -175,8 +174,8 @@ public abstract class AppendWarningNode extends Node {
}
@Specialization(guards = "isError(object)")
EnsoObject dontAnnotateError(Object object, Object ignoreWarnings) {
return (EnsoObject) object;
Object dontAnnotateError(Object object, Object ignoreWarnings) {
return object;
}
/** Inserts all {@code warnings} to the {@code initialWarningMap}. */

View File

@ -20,8 +20,9 @@ import org.enso.interpreter.runtime.library.dispatch.TypesLibrary;
@Builtin(pkg = "error", stdlibName = "Standard.Base.Warning.Warning")
@ExportLibrary(TypesLibrary.class)
public final class Warning implements EnsoObject {
private final Object value;
@ExportLibrary(value = InteropLibrary.class, delegateTo = "value")
public final class Warning extends EnsoObject {
final Object value;
private final Object origin;
private final long sequenceId;
@ -57,7 +58,8 @@ public final class Warning implements EnsoObject {
description = "Attaches the given warning to the value.",
autoRegister = false)
@Builtin.Specialize
public static EnsoObject attach(
@SuppressWarnings("generic-enso-builtin-type")
public static Object attach(
EnsoContext ctx,
Object value,
Object warning,
@ -105,6 +107,18 @@ public final class Warning implements EnsoObject {
return map;
}
@ExportMessage
@TruffleBoundary
@Override
public Object toDisplayString(boolean enableSideEffects) {
return toString();
}
@ExportMessage
boolean isNull() {
return false;
}
@CompilerDirectives.TruffleBoundary
@Override
public String toString() {

View File

@ -1,6 +1,7 @@
package org.enso.interpreter.runtime.warning;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.dsl.Bind;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.Cached.Shared;
@ -54,7 +55,7 @@ import org.enso.interpreter.runtime.state.State;
@ExportLibrary(WarningsLibrary.class)
@ExportLibrary(ReflectionLibrary.class)
@ExportLibrary(value = InteropLibrary.class, delegateTo = "value")
public final class WithWarnings implements EnsoObject {
public final class WithWarnings extends EnsoObject {
final Object value;
/**
@ -270,6 +271,19 @@ public final class WithWarnings implements EnsoObject {
throw asException(node);
}
@TruffleBoundary
@Override
@ExportMessage.Ignore
public Object toDisplayString(boolean allowSideEffects) {
return toDisplayString(allowSideEffects, InteropLibrary.getUncached());
}
@ExportMessage
public Object toDisplayString(
boolean allowSideEffects, @CachedLibrary("this.value") InteropLibrary interop) {
return interop.toDisplayString(value, allowSideEffects);
}
@Override
public String toString() {
return "WithWarnings{"