From e261e8dd821c5ae4283f847a3a6538d53c6ec3ae Mon Sep 17 00:00:00 2001 From: Jaroslav Tulach Date: Thu, 30 Jan 2025 20:55:59 +0100 Subject: [PATCH 01/26] Use BuiltinRootNode.ArgNode to extract argument for a builtin method --- .../node/expression/builtin/Any.java | 7 +- .../node/expression/builtin/Boolean.java | 6 +- .../node/expression/builtin/Builtin.java | 22 ++- .../expression/builtin/BuiltinRootNode.java | 118 +++++++++++- .../node/expression/builtin/Error.java | 7 +- .../node/expression/builtin/Nothing.java | 6 +- .../node/expression/builtin/Polyglot.java | 6 +- .../builtin/UniquelyConstructibleBuiltin.java | 4 + .../node/expression/builtin/debug/Debug.java | 6 +- .../builtin/error/NumberParseError.java | 4 + .../node/expression/builtin/error/Panic.java | 7 +- .../builtin/error/ProblemBehavior.java | 5 +- .../expression/builtin/function/Function.java | 6 +- .../node/expression/builtin/number/Float.java | 4 + .../expression/builtin/number/Integer.java | 4 + .../expression/builtin/number/Number.java | 4 + .../builtin/ordering/Comparable.java | 5 + .../builtin/ordering/DefaultComparator.java | 6 +- .../expression/builtin/ordering/Ordering.java | 4 + .../expression/builtin/runtime/Context.java | 6 +- .../builtin/text/PrimTextHelper.java | 6 +- .../node/expression/builtin/text/Text.java | 4 + .../interpreter/runtime/builtin/Builtins.java | 9 + .../interpreter/dsl/BuiltinsProcessor.java | 13 +- .../enso/interpreter/dsl/MethodProcessor.java | 176 +++++++++--------- 25 files changed, 336 insertions(+), 109 deletions(-) diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/Any.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/Any.java index 87a10fb07b3d..3bab19464df8 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/Any.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/Any.java @@ -1,9 +1,14 @@ package org.enso.interpreter.node.expression.builtin; +import com.oracle.truffle.api.interop.TruffleObject; import org.enso.interpreter.dsl.BuiltinType; @BuiltinType(name = "Standard.Base.Any.Any") -public class Any extends Builtin { +public final class Any extends Builtin { + public Any() { + super(TruffleObject.class); + } + @Override public Class getSuperType() { return null; diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/Boolean.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/Boolean.java index 7baf88ca1394..f5a31d3d5b04 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/Boolean.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/Boolean.java @@ -10,7 +10,11 @@ // Before moving this definition to the `bool` package, as we should, one would have to address that // problem first. @BuiltinType(name = "Standard.Base.Data.Boolean.Boolean") -public class Boolean extends Builtin { +public final class Boolean extends Builtin { + public Boolean() { + super(java.lang.Boolean.class); + } + @Override protected List getDeclaredConstructors() { return List.of(new Cons("False"), new Cons("True")); diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/Builtin.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/Builtin.java index cb5585093204..e6fa11d8c51a 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/Builtin.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/Builtin.java @@ -33,15 +33,33 @@ private AtomConstructor build(EnsoLanguage language, ModuleScope.Builder scope, } } + private final Class representationType; private final String name; - public Builtin() { - name = this.getClass().getSimpleName().replaceAll("([^_A-Z])([A-Z])", "$1_$2"); + protected Builtin(String representationType) { + this(findType(representationType)); + } + + protected Builtin(Class representationType) { + this.representationType = representationType; + this.name = this.getClass().getSimpleName().replaceAll("([^_A-Z])([A-Z])", "$1_$2"); + } + + private static Class findType(String fqn) { + try { + return Class.forName(fqn); + } catch (ClassNotFoundException ex) { + throw new IllegalArgumentException(ex); + } } private @CompilerDirectives.CompilationFinal Type type; private @CompilerDirectives.CompilationFinal(dimensions = 1) AtomConstructor[] constructors; + public final boolean isRepresentedBy(Class clazz) { + return representationType == clazz; + } + protected Class getSuperType() { return Any.class; } diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/BuiltinRootNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/BuiltinRootNode.java index f845b53fefc4..a4368a60c7c2 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/BuiltinRootNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/BuiltinRootNode.java @@ -1,21 +1,33 @@ package org.enso.interpreter.node.expression.builtin; +import com.oracle.truffle.api.CompilerDirectives; +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.frame.VirtualFrame; +import com.oracle.truffle.api.interop.TruffleObject; +import com.oracle.truffle.api.nodes.ControlFlowException; +import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.nodes.NodeInfo; import com.oracle.truffle.api.nodes.RootNode; import org.enso.interpreter.EnsoLanguage; +import org.enso.interpreter.runtime.EnsoContext; +import org.enso.interpreter.runtime.data.EnsoMultiValue; +import org.enso.interpreter.runtime.data.Type; +import org.enso.interpreter.runtime.error.DataflowError; +import org.enso.interpreter.runtime.error.PanicException; import org.enso.pkg.QualifiedName; /** Root node for use by all the builtin functions. */ @NodeInfo(shortName = "BuiltinRoot", description = "Root node for builtin functions.") public abstract class BuiltinRootNode extends RootNode { + private QualifiedName moduleName; + private QualifiedName typeName; + protected BuiltinRootNode(EnsoLanguage language) { super(language); } - protected QualifiedName moduleName = null; - protected QualifiedName typeName = null; - /** Get the module name where the builtin is defined. */ public QualifiedName getModuleName() { return moduleName; @@ -52,4 +64,104 @@ public void setTypeName(QualifiedName typeName) { */ @Override public abstract String getName(); + + protected static final class ReturnValue extends ControlFlowException { + private final TruffleObject value; + + private ReturnValue(TruffleObject value) { + this.value = value; + } + + public TruffleObject get() { + return value; + } + } + + protected abstract static class ArgNode extends Node { + private final boolean isSelf; + private final boolean isArray; + private final boolean requiresCast; + private final boolean checkErrors; + private final boolean checkPanicSentinel; + private final boolean checkWarnings; + @CompilerDirectives.CompilationFinal private Type ensoType; + + ArgNode( + boolean isSelf, + boolean isArray, + boolean requiresCast, + boolean checkErrors, + boolean checkPanicSentinel, + boolean checkWarnings) { + this.isSelf = isSelf; + this.isArray = isArray; + this.requiresCast = requiresCast; + this.checkErrors = checkErrors; + this.checkPanicSentinel = checkPanicSentinel; + this.checkWarnings = checkWarnings; + } + + @SuppressWarnings("unchecked") + public final T processArgument(Class type, Object value) throws ReturnValue { + if (checkErrors && value instanceof DataflowError err) { + throw new ReturnValue(err); + } + var ctx = EnsoContext.get(this); + if (this.ensoType == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + var builtin = ctx.getBuiltins().getByRepresentationType(type); + if (builtin == null) { + System.err.println("found no builtin for " + type); + this.ensoType = ctx.getBuiltins().any(); + } else { + this.ensoType = builtin.getType(); + } + } + assert value != null; + var conv = executeConversion(value); + if (conv == null) { + CompilerDirectives.transferToInterpreter(); + var err = ctx.getBuiltins().error().makeTypeError(this.ensoType, value, type.getName()); + throw new PanicException(err, this); + } + return type.cast(conv); + } + + abstract Object executeConversion(Object obj); + + @Specialization + final Object extractMultiValue(EnsoMultiValue emv, @Cached EnsoMultiValue.CastToNode castTo) { + var extracted = castTo.findTypeOrNull(ensoType, emv, false, false); + return extracted; + } + + @Fallback + final Object justReturnIt(Object obj) { + return obj; + } + + public static ArgNode create( + boolean isSelf, + boolean isArray, + boolean requiresCast, + boolean checkErrors, + boolean checkPanicSentinel, + boolean checkWarnings) { + return BuiltinRootNodeFactory.ArgNodeGen.create( + isSelf, isArray, requiresCast, checkErrors, checkPanicSentinel, checkWarnings); + } + + /* + if (!arg.requiresCast()) { + generateUncastedArgumentRead(out, arg, argsArray); + } else if (arg.isSelf()) { + generateUncheckedArgumentRead(out, arg, argsArray); + } else if (arg.isArray()) { + generateUncheckedArrayCast(out, arg, argsArray); + } else { + generateCheckedArgumentRead(out, arg, argsArray); + } + + */ + } } diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/Error.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/Error.java index 690ae5846424..1e879533016f 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/Error.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/Error.java @@ -1,9 +1,14 @@ package org.enso.interpreter.node.expression.builtin; import org.enso.interpreter.dsl.BuiltinType; +import org.enso.interpreter.runtime.error.DataflowError; @BuiltinType(name = "Standard.Base.Error.Error") -public class Error extends Builtin { +public final class Error extends Builtin { + public Error() { + super(DataflowError.class); + } + @Override protected Class getSuperType() { return null; diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/Nothing.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/Nothing.java index a62815bcc712..a3f1ddd24ed7 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/Nothing.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/Nothing.java @@ -3,7 +3,11 @@ import org.enso.interpreter.dsl.BuiltinType; @BuiltinType(name = "Standard.Base.Nothing.Nothing") -public class Nothing extends Builtin { +public final class Nothing extends Builtin { + public Nothing() { + super(Void.class); + } + @Override public boolean containsValues() { return false; diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/Polyglot.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/Polyglot.java index 1e76617c06db..ac41b610ad4e 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/Polyglot.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/Polyglot.java @@ -3,4 +3,8 @@ import org.enso.interpreter.dsl.BuiltinType; @BuiltinType -public class Polyglot extends Builtin {} +public final class Polyglot extends Builtin { + public Polyglot() { + super(Object.class); + } +} diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/UniquelyConstructibleBuiltin.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/UniquelyConstructibleBuiltin.java index c8c3cc987a7e..97d8f8b81029 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/UniquelyConstructibleBuiltin.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/UniquelyConstructibleBuiltin.java @@ -9,6 +9,10 @@ public abstract class UniquelyConstructibleBuiltin extends Builtin { private @CompilerDirectives.CompilationFinal AtomConstructor uniqueConstructor; + protected UniquelyConstructibleBuiltin() { + super(Object.class); + } + public final AtomConstructor getUniqueConstructor() { return uniqueConstructor; } diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/debug/Debug.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/debug/Debug.java index 2c5909e209f0..0b2303c9e0c5 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/debug/Debug.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/debug/Debug.java @@ -4,4 +4,8 @@ import org.enso.interpreter.node.expression.builtin.Builtin; @BuiltinType -public class Debug extends Builtin {} +public class Debug extends Builtin { + public Debug() { + super(Object.class); + } +} diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/error/NumberParseError.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/error/NumberParseError.java index b715f5fd3549..a38375a579fc 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/error/NumberParseError.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/error/NumberParseError.java @@ -8,6 +8,10 @@ @BuiltinType public final class NumberParseError extends Builtin { + public NumberParseError() { + super(Object.class); + } + @Override protected final List getDeclaredConstructors() { return List.of(new Cons("Error", "text")); diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/error/Panic.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/error/Panic.java index 7ddffad71851..738370a0e0e6 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/error/Panic.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/error/Panic.java @@ -2,9 +2,14 @@ import org.enso.interpreter.dsl.BuiltinType; import org.enso.interpreter.node.expression.builtin.Builtin; +import org.enso.interpreter.runtime.error.PanicException; @BuiltinType(name = "Standard.Base.Panic.Panic") -public class Panic extends Builtin { +public final class Panic extends Builtin { + public Panic() { + super(PanicException.class); + } + @Override public boolean containsValues() { return true; diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/error/ProblemBehavior.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/error/ProblemBehavior.java index a5c89445ff31..3da76176d84d 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/error/ProblemBehavior.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/error/ProblemBehavior.java @@ -6,7 +6,10 @@ import org.enso.interpreter.runtime.data.atom.AtomConstructor; @BuiltinType(name = "Standard.Base.Errors.Problem_Behavior.Problem_Behavior") -public class ProblemBehavior extends Builtin { +public final class ProblemBehavior extends Builtin { + public ProblemBehavior() { + super(Object.class); + } @Override protected List getDeclaredConstructors() { diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/function/Function.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/function/Function.java index b08fd89f5108..3e95da65c756 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/function/Function.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/function/Function.java @@ -4,7 +4,11 @@ import org.enso.interpreter.node.expression.builtin.Builtin; @BuiltinType(name = "Standard.Base.Function.Function") -public class Function extends Builtin { +public final class Function extends Builtin { + public Function() { + super(org.enso.interpreter.runtime.callable.function.Function.class); + } + @Override public boolean containsValues() { return true; diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/Float.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/Float.java index b65f7e4908b1..59714f594fe4 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/Float.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/Float.java @@ -5,6 +5,10 @@ @BuiltinType(name = "Standard.Base.Data.Numbers.Float") public class Float extends Builtin { + public Float() { + super(Double.class); + } + @Override protected Class getSuperType() { return Number.class; diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/Integer.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/Integer.java index 296f7521dc95..2a321982daa3 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/Integer.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/Integer.java @@ -5,6 +5,10 @@ @BuiltinType(name = "Standard.Base.Data.Numbers.Integer") public class Integer extends Builtin { + public Integer() { + super(Long.class); + } + @Override protected Class getSuperType() { return Number.class; diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/Number.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/Number.java index d09c5c674068..f21bc95c6b05 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/Number.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/Number.java @@ -5,6 +5,10 @@ @BuiltinType(name = "Standard.Base.Data.Numbers.Number") public class Number extends Builtin { + public Number() { + super(Number.class); + } + @Override public boolean containsValues() { return true; diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/ordering/Comparable.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/ordering/Comparable.java index 5b807b4a7f7c..1b5fa797b13e 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/ordering/Comparable.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/ordering/Comparable.java @@ -8,6 +8,11 @@ /** A hidden builtin. Only conversions with target type of Comparable are visible. */ @BuiltinType public final class Comparable extends Builtin { + + public Comparable() { + super(Object.class); + } + @Override protected List getDeclaredConstructors() { return List.of(new Cons("By", List.of("value", "comparator"))); diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/ordering/DefaultComparator.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/ordering/DefaultComparator.java index 5d31539c549f..63cc6980058f 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/ordering/DefaultComparator.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/ordering/DefaultComparator.java @@ -4,4 +4,8 @@ import org.enso.interpreter.node.expression.builtin.Builtin; @BuiltinType -public class DefaultComparator extends Builtin {} +public final class DefaultComparator extends Builtin { + public DefaultComparator() { + super(Object.class); + } +} diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/ordering/Ordering.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/ordering/Ordering.java index de2167e2a963..29312f7922be 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/ordering/Ordering.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/ordering/Ordering.java @@ -9,6 +9,10 @@ @BuiltinType public class Ordering extends Builtin { + public Ordering() { + super(Object.class); + } + @Override protected List getDeclaredConstructors() { return List.of(new Cons("Less"), new Cons("Equal"), new Cons("Greater")); diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/runtime/Context.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/runtime/Context.java index 4dbc4a117e39..88e73b9eaf16 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/runtime/Context.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/runtime/Context.java @@ -6,7 +6,11 @@ import org.enso.interpreter.runtime.data.atom.AtomConstructor; @BuiltinType -public class Context extends Builtin { +public final class Context extends Builtin { + public Context() { + super(Object.class); + } + @Override protected List getDeclaredConstructors() { return List.of( diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/text/PrimTextHelper.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/text/PrimTextHelper.java index 27eabf1e0738..bc77eed39b3d 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/text/PrimTextHelper.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/text/PrimTextHelper.java @@ -4,4 +4,8 @@ import org.enso.interpreter.node.expression.builtin.Builtin; @BuiltinType -public class PrimTextHelper extends Builtin {} +public class PrimTextHelper extends Builtin { + public PrimTextHelper() { + super(Object.class); + } +} diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/text/Text.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/text/Text.java index 80aa8f8471e8..b520355e62f3 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/text/Text.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/text/Text.java @@ -5,6 +5,10 @@ @BuiltinType(name = "Standard.Base.Data.Text.Text") public class Text extends Builtin { + public Text() { + super(org.enso.interpreter.runtime.data.text.Text.class); + } + @Override public boolean containsValues() { return true; diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/builtin/Builtins.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/builtin/Builtins.java index 438ec095b554..523dc0459d35 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/builtin/Builtins.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/builtin/Builtins.java @@ -525,6 +525,15 @@ public T getBuiltinType(Class clazz) { return t; } + public Builtin getByRepresentationType(Class clazz) { + for (var b : builtins.values()) { + if (b.isRepresentedBy(clazz)) { + return b; + } + } + return null; + } + public Builtin getBuiltinType(String name) { return builtinsByName.get(name); } diff --git a/lib/scala/interpreter-dsl/src/main/java/org/enso/interpreter/dsl/BuiltinsProcessor.java b/lib/scala/interpreter-dsl/src/main/java/org/enso/interpreter/dsl/BuiltinsProcessor.java index 6d9a4322ece3..2d0a9f8dc529 100644 --- a/lib/scala/interpreter-dsl/src/main/java/org/enso/interpreter/dsl/BuiltinsProcessor.java +++ b/lib/scala/interpreter-dsl/src/main/java/org/enso/interpreter/dsl/BuiltinsProcessor.java @@ -101,15 +101,14 @@ public void handleClassElement(Element element, RoundEnvironment roundEnv) throw processingEnv.getFiler().createSourceFile(builtinType.fullyQualifiedName()); Optional stdLibName = annotation.stdlibName().isEmpty() ? Optional.empty() : Optional.of(annotation.stdlibName()); - generateBuiltinType( - gen, builtinType, stdLibName, elt.getSimpleName().toString(), annotation.containsValues()); + generateBuiltinType(gen, builtinType, stdLibName, elt, annotation.containsValues()); } private void generateBuiltinType( JavaFileObject gen, ClassName builtinType, Optional stdLibName, - String underlyingTypeName, + TypeElement forElement, boolean containsValues) throws IOException { try (PrintWriter out = new PrintWriter(gen.openWriter())) { @@ -123,10 +122,14 @@ private void generateBuiltinType( "@BuiltinType(" + stdLibName.map(n -> "name = \"" + n + "\", ").orElse("") + "underlyingTypeName = \"" - + underlyingTypeName + + forElement.getSimpleName().toString() + "\")"; out.println(builtinTypeAnnotation); - out.println("public class " + builtinType.name() + " extends Builtin {"); + out.println("public final class " + builtinType.name() + " extends Builtin {"); + out.println(" public " + builtinType.name() + "() {"); + var fqn = processingEnv.getElementUtils().getBinaryName(forElement); + out.println(" super(\"" + fqn + "\");"); + out.println(" }"); out.println(""" @Override public boolean containsValues() { diff --git a/lib/scala/interpreter-dsl/src/main/java/org/enso/interpreter/dsl/MethodProcessor.java b/lib/scala/interpreter-dsl/src/main/java/org/enso/interpreter/dsl/MethodProcessor.java index a4458a2268dd..bf5051b16726 100644 --- a/lib/scala/interpreter-dsl/src/main/java/org/enso/interpreter/dsl/MethodProcessor.java +++ b/lib/scala/interpreter-dsl/src/main/java/org/enso/interpreter/dsl/MethodProcessor.java @@ -203,36 +203,33 @@ private void generateCode(MethodDefinition methodDefinition) throws IOException + " WarningsLibrary.getFactory().createDispatched(5);"); out.println( " private @Child HashMapInsertAllNode mapInsertAllNode = HashMapInsertAllNode.build();"); - out.println(); + out.println(" @Children private ArgNode[] argNodes = new ArgNode[] {"); + for (MethodDefinition.ArgumentDefinition arg : methodDefinition.getArguments()) { + var checkErrors = arg.shouldCheckErrors(); + var checkPanicSentinel = arg.isPositional() && !arg.isSelf(); + var checkWarnings = arg.shouldCheckWarnings(); + out.println( + " ArgNode.create(" + + arg.isSelf() + + ", " + + arg.isArray() + + ", " + + arg.requiresCast() + + ", " + + checkErrors + + ", " + + checkPanicSentinel + + ", " + + checkWarnings + + "),"); + } + out.println(" };"); out.println(" private static final class Internals {"); out.println(" Internals(boolean s) {"); out.println(" this.staticOrInstanceMethod = s;"); out.println(" }"); out.println(); out.println(" private final boolean staticOrInstanceMethod;"); - - for (MethodDefinition.ArgumentDefinition arg : methodDefinition.getArguments()) { - if (arg.shouldCheckErrors()) { - String condName = mkArgumentInternalVarName(arg) + DATAFLOW_ERROR_PROFILE; - out.println( - " private final CountingConditionProfile " - + condName - + " = CountingConditionProfile.create();"); - } - - if (arg.isPositional() && !arg.isSelf()) { - String branchName = mkArgumentInternalVarName(arg) + PANIC_SENTINEL_PROFILE; - out.println( - " private final BranchProfile " + branchName + " = BranchProfile.create();"); - } - - if (arg.shouldCheckWarnings()) { - String warningName = mkArgumentInternalVarName(arg) + WARNING_PROFILE; - out.println( - " private final BranchProfile " + warningName + " = BranchProfile.create();"); - } - } - out.println(" private final BranchProfile anyWarningsProfile = BranchProfile.create();"); out.println(" }"); out.println(" private final Internals internals;"); @@ -304,11 +301,31 @@ private void generateCode(MethodDefinition methodDefinition) throws IOException out.println( " private @Child HashMapInsertAllNode mapInsertAllNode =" + " HashMapInsertAllNode.build();"); - out.println(); + out.println(" @Children private ArgNode[] argNodes = new ArgNode[] {"); + for (MethodDefinition.ArgumentDefinition arg : methodDefinition.getArguments()) { + var checkErrors = arg.shouldCheckErrors(); + var checkPanicSentinel = arg.isPositional() && !arg.isSelf(); + var checkWarnings = arg.shouldCheckWarnings(); + out.println( + " ArgNode.create(" + + arg.isSelf() + + ", " + + arg.isArray() + + ", " + + arg.requiresCast() + + ", " + + checkErrors + + ", " + + checkPanicSentinel + + ", " + + checkWarnings + + "),"); + } + out.println(" };"); out.println(" @Override"); out.println(" public Object call(VirtualFrame frame, Object[] args) {"); out.println( - " return handleExecute(frame, extra, body, appendWarningNode, warnLib," + " return handleExecute(argNodes, frame, extra, body, appendWarningNode, warnLib," + " mapInsertAllNode, args);"); out.println(" }"); out.println(" }"); @@ -325,11 +342,13 @@ private void generateCode(MethodDefinition methodDefinition) throws IOException out.println(" var args = frame.getArguments();"); } else { out.println( - " return handleExecute(frame, this.internals, bodyNode, this.appendWarningNode," - + " this.warnLib, this.mapInsertAllNode, frame.getArguments());"); + " return handleExecute(argNodes, frame, this.internals, bodyNode," + + " this.appendWarningNode, this.warnLib, this.mapInsertAllNode," + + " frame.getArguments());"); out.println(" }"); out.println( - " private static Object handleExecute(VirtualFrame frame, Internals internals, " + " private static Object handleExecute(ArgNode[] argNodes, VirtualFrame frame," + + " Internals internals, " + methodDefinition.getOriginalClassName() + " bodyNode, AppendWarningNode appendWarningNode, WarningsLibrary warnLib," + " HashMapInsertAllNode mapInsertAllNode, Object[] args) {"); @@ -352,29 +371,25 @@ private void generateCode(MethodDefinition methodDefinition) throws IOException " int arg" + arg.getPosition() + "Idx = " + arg.getPosition() + " + prefix;"); } } + out.println(" try {"); boolean warningsPossible = generateWarningsCheck(out, methodDefinition.getArguments(), "arguments"); - for (MethodDefinition.ArgumentDefinition argumentDefinition : - methodDefinition.getArguments()) { - out.println( - " /*** Start of processing argument " - + argumentDefinition.getPosition() - + " ***/"); - if (argumentDefinition.isImplicit()) { - } else if (argumentDefinition.isState()) { + for (MethodDefinition.ArgumentDefinition ad : methodDefinition.getArguments()) { + out.println(" /*** Start of processing argument " + ad.getPosition() + " ***/"); + if (ad.isImplicit()) { + } else if (ad.isState()) { callArgNames.add("state"); - } else if (argumentDefinition.isFrame()) { + } else if (ad.isFrame()) { callArgNames.add("frame"); - } else if (argumentDefinition.isNode()) { + } else if (ad.isNode()) { callArgNames.add("bodyNode"); - } else if (argumentDefinition.isCallerInfo()) { + } else if (ad.isCallerInfo()) { callArgNames.add("callerInfo"); } else { - callArgNames.add(mkArgumentInternalVarName(argumentDefinition)); - generateArgumentRead(out, argumentDefinition, "arguments"); + callArgNames.add(mkArgumentInternalVarName(ad)); + generateArgumentRead(out, ad, "arguments"); } - out.println( - " /*** End of processing argument " + argumentDefinition.getPosition() + " ***/"); + out.println(" /*** End of processing argument " + ad.getPosition() + " ***/"); } String executeCall = "bodyNode.execute(" + String.join(", ", callArgNames) + ")"; if (warningsPossible) { @@ -390,6 +405,9 @@ private void generateCode(MethodDefinition methodDefinition) throws IOException } else { out.println(wrapInTryCatch("return " + executeCall + ";", 6)); } + out.println(" } catch (ReturnValue ex) {"); + out.println(" return ex.get();"); + out.println(" }"); out.println(" }"); out.println(); @@ -479,48 +497,33 @@ private List generateMakeFunctionArgs( return argumentDefs; } - private void generateArgumentRead( - PrintWriter out, MethodDefinition.ArgumentDefinition arg, String argsArray) { - String argReference = argsArray + "[arg" + arg.getPosition() + "Idx]"; - if (arg.shouldCheckErrors()) { - String condProfile = mkArgumentInternalVarName(arg) + DATAFLOW_ERROR_PROFILE; - out.println( - " if (internals." - + condProfile - + ".profile(TypesGen.isDataflowError(" - + argReference - + "))) {\n" - + " return " - + argReference - + ";\n" - + " }"); - } - if (!arg.isSelf()) { - String branchProfile = mkArgumentInternalVarName(arg) + PANIC_SENTINEL_PROFILE; - out.println( - " if (TypesGen.isPanicSentinel(" - + argReference - + ")) {\n" - + " internals." - + branchProfile - + ".enter();\n" - + " throw TypesGen.asPanicSentinel(" - + argReference - + ");\n" - + " }"); - } - - if (!arg.requiresCast()) { - generateUncastedArgumentRead(out, arg, argsArray); - } else if (arg.isSelf()) { - generateUncheckedArgumentRead(out, arg, argsArray); - } else if (arg.isArray()) { - generateUncheckedArrayCast(out, arg, argsArray); + private String wrapperTypeName(MethodDefinition.ArgumentDefinition arg) { + var tn = capitalize(arg.getTypeName()); + if ("Boolean".equals(tn)) { + return "java.lang.Boolean"; } else { - generateCheckedArgumentRead(out, arg, argsArray); + return tn; } } + private void generateArgumentRead( + PrintWriter out, MethodDefinition.ArgumentDefinition arg, String argsArray) { + var argReference = argsArray + "[arg" + arg.getPosition() + "Idx]"; + var varName = mkArgumentInternalVarName(arg); + out.println( + " " + + arg.getTypeName() + + " " + + varName + + " = argNodes[" + + arg.getPosition() + + "].processArgument(" + + wrapperTypeName(arg) + + ".class, " + + argReference + + ");"); + } + private void generateUncastedArgumentRead( PrintWriter out, MethodDefinition.ArgumentDefinition arg, String argsArray) { String varName = mkArgumentInternalVarName(arg); @@ -626,6 +629,9 @@ private void generateCheckedArgumentRead( private boolean generateWarningsCheck( PrintWriter out, List arguments, String argumentsArray) { + if (true) { + return false; + } List argsToCheck = arguments.stream() .filter(ArgumentDefinition::shouldCheckWarnings) @@ -643,7 +649,7 @@ private boolean generateWarningsCheck( + arrayRead(argumentsArray, arg.getPosition()) + " instanceof WithWarnings withWarnings) {"); out.println( - " internals." + mkArgumentInternalVarName(arg) + WARNING_PROFILE + ".enter();"); + " internals." + mkArgumentInternalVarName(arg) + "warnProfile" + ".enter();"); out.println(" anyWarnings = true;"); out.println(" try {"); // begin try out.println(" var warns = warnLib.getWarnings(withWarnings, false);"); @@ -751,8 +757,4 @@ protected MethodMetadataEntry toMetadataEntry(String line) { Boolean.parseBoolean(elements[2]), Boolean.parseBoolean(elements[3])); } - - private static final String DATAFLOW_ERROR_PROFILE = "IsDataflowErrorConditionProfile"; - private static final String PANIC_SENTINEL_PROFILE = "PanicSentinelBranchProfile"; - private static final String WARNING_PROFILE = "WarningProfile"; } From 5847b0f2c55336947fe913de940798b958e05e09 Mon Sep 17 00:00:00 2001 From: Jaroslav Tulach Date: Thu, 30 Jan 2025 21:12:14 +0100 Subject: [PATCH 02/26] Gathering info from all arguments via ArgContext --- .../expression/builtin/BuiltinRootNode.java | 19 ++++++++----------- .../enso/interpreter/dsl/MethodProcessor.java | 8 +++----- 2 files changed, 11 insertions(+), 16 deletions(-) diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/BuiltinRootNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/BuiltinRootNode.java index a4368a60c7c2..c1e4805c3529 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/BuiltinRootNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/BuiltinRootNode.java @@ -6,7 +6,6 @@ import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.interop.TruffleObject; -import com.oracle.truffle.api.nodes.ControlFlowException; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.nodes.NodeInfo; import com.oracle.truffle.api.nodes.RootNode; @@ -65,15 +64,13 @@ public void setTypeName(QualifiedName typeName) { @Override public abstract String getName(); - protected static final class ReturnValue extends ControlFlowException { - private final TruffleObject value; + protected static final class ArgContext { + private TruffleObject returnValue; - private ReturnValue(TruffleObject value) { - this.value = value; - } + public ArgContext() {} - public TruffleObject get() { - return value; + public TruffleObject getReturnValue() { + return returnValue; } } @@ -102,16 +99,16 @@ protected abstract static class ArgNode extends Node { } @SuppressWarnings("unchecked") - public final T processArgument(Class type, Object value) throws ReturnValue { + public final T processArgument(Class type, Object value, ArgContext context) { if (checkErrors && value instanceof DataflowError err) { - throw new ReturnValue(err); + context.returnValue = err; + return null; } var ctx = EnsoContext.get(this); if (this.ensoType == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); var builtin = ctx.getBuiltins().getByRepresentationType(type); if (builtin == null) { - System.err.println("found no builtin for " + type); this.ensoType = ctx.getBuiltins().any(); } else { this.ensoType = builtin.getType(); diff --git a/lib/scala/interpreter-dsl/src/main/java/org/enso/interpreter/dsl/MethodProcessor.java b/lib/scala/interpreter-dsl/src/main/java/org/enso/interpreter/dsl/MethodProcessor.java index bf5051b16726..bddbf065dd20 100644 --- a/lib/scala/interpreter-dsl/src/main/java/org/enso/interpreter/dsl/MethodProcessor.java +++ b/lib/scala/interpreter-dsl/src/main/java/org/enso/interpreter/dsl/MethodProcessor.java @@ -371,7 +371,7 @@ private void generateCode(MethodDefinition methodDefinition) throws IOException " int arg" + arg.getPosition() + "Idx = " + arg.getPosition() + " + prefix;"); } } - out.println(" try {"); + out.println(" var argCtx = new ArgContext();"); boolean warningsPossible = generateWarningsCheck(out, methodDefinition.getArguments(), "arguments"); for (MethodDefinition.ArgumentDefinition ad : methodDefinition.getArguments()) { @@ -391,6 +391,7 @@ private void generateCode(MethodDefinition methodDefinition) throws IOException } out.println(" /*** End of processing argument " + ad.getPosition() + " ***/"); } + out.println(" if (argCtx.getReturnValue() != null) return argCtx.getReturnValue();"); String executeCall = "bodyNode.execute(" + String.join(", ", callArgNames) + ")"; if (warningsPossible) { out.println(" if (anyWarnings) {"); @@ -405,9 +406,6 @@ private void generateCode(MethodDefinition methodDefinition) throws IOException } else { out.println(wrapInTryCatch("return " + executeCall + ";", 6)); } - out.println(" } catch (ReturnValue ex) {"); - out.println(" return ex.get();"); - out.println(" }"); out.println(" }"); out.println(); @@ -521,7 +519,7 @@ private void generateArgumentRead( + wrapperTypeName(arg) + ".class, " + argReference - + ");"); + + ", argCtx);"); } private void generateUncastedArgumentRead( From b64693255ad562059d23ed8cbfb38a5ff017afc6 Mon Sep 17 00:00:00 2001 From: Jaroslav Tulach Date: Fri, 31 Jan 2025 04:47:40 +0100 Subject: [PATCH 03/26] Compressing flags into a byte --- .../expression/builtin/BuiltinRootNode.java | 56 +++++++++++-------- 1 file changed, 34 insertions(+), 22 deletions(-) diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/BuiltinRootNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/BuiltinRootNode.java index c1e4805c3529..0a3312872294 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/BuiltinRootNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/BuiltinRootNode.java @@ -75,32 +75,26 @@ public TruffleObject getReturnValue() { } protected abstract static class ArgNode extends Node { - private final boolean isSelf; - private final boolean isArray; - private final boolean requiresCast; - private final boolean checkErrors; - private final boolean checkPanicSentinel; - private final boolean checkWarnings; + private static final byte IS_SELF = 0x01; + private static final byte IS_ARRAY = 0x02; + private static final byte REQUIRES_CAST = 0x04; + private static final byte CHECK_ERRORS = 0x08; + private static final byte CHECK_PANIC_SENTINEL = 0x10; + private static final byte CHECK_WARNINGS = 0x20; + private final byte flags; @CompilerDirectives.CompilationFinal private Type ensoType; - ArgNode( - boolean isSelf, - boolean isArray, - boolean requiresCast, - boolean checkErrors, - boolean checkPanicSentinel, - boolean checkWarnings) { - this.isSelf = isSelf; - this.isArray = isArray; - this.requiresCast = requiresCast; - this.checkErrors = checkErrors; - this.checkPanicSentinel = checkPanicSentinel; - this.checkWarnings = checkWarnings; + ArgNode(byte flags) { + this.flags = flags; + } + + final boolean is(byte what) { + return (flags & what) != 0; } @SuppressWarnings("unchecked") public final T processArgument(Class type, Object value, ArgContext context) { - if (checkErrors && value instanceof DataflowError err) { + if (is(CHECK_ERRORS) && value instanceof DataflowError err) { context.returnValue = err; return null; } @@ -144,8 +138,26 @@ public static ArgNode create( boolean checkErrors, boolean checkPanicSentinel, boolean checkWarnings) { - return BuiltinRootNodeFactory.ArgNodeGen.create( - isSelf, isArray, requiresCast, checkErrors, checkPanicSentinel, checkWarnings); + byte flags = 0x00; + if (isSelf) { + flags |= IS_SELF; + } + if (isArray) { + flags |= IS_ARRAY; + } + if (requiresCast) { + flags |= REQUIRES_CAST; + } + if (checkErrors) { + flags |= CHECK_ERRORS; + } + if (checkPanicSentinel) { + flags |= CHECK_PANIC_SENTINEL; + } + if (checkWarnings) { + flags |= CHECK_WARNINGS; + } + return BuiltinRootNodeFactory.ArgNodeGen.create(flags); } /* From 20fa9c3b5c55827768daa2ebc3a722acc236fe98 Mon Sep 17 00:00:00 2001 From: Jaroslav Tulach Date: Fri, 31 Jan 2025 05:09:34 +0100 Subject: [PATCH 04/26] Only convert when is(REQUIRES_CAST) --- .../expression/builtin/BuiltinRootNode.java | 42 +++++++++++-------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/BuiltinRootNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/BuiltinRootNode.java index 0a3312872294..5294a325fc20 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/BuiltinRootNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/BuiltinRootNode.java @@ -15,6 +15,7 @@ import org.enso.interpreter.runtime.data.Type; import org.enso.interpreter.runtime.error.DataflowError; import org.enso.interpreter.runtime.error.PanicException; +import org.enso.interpreter.runtime.error.PanicSentinel; import org.enso.pkg.QualifiedName; /** Root node for use by all the builtin functions. */ @@ -88,34 +89,41 @@ protected abstract static class ArgNode extends Node { this.flags = flags; } - final boolean is(byte what) { + private boolean is(byte what) { return (flags & what) != 0; } @SuppressWarnings("unchecked") public final T processArgument(Class type, Object value, ArgContext context) { + assert value != null; if (is(CHECK_ERRORS) && value instanceof DataflowError err) { context.returnValue = err; return null; } - var ctx = EnsoContext.get(this); - if (this.ensoType == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - var builtin = ctx.getBuiltins().getByRepresentationType(type); - if (builtin == null) { - this.ensoType = ctx.getBuiltins().any(); - } else { - this.ensoType = builtin.getType(); - } + if (is(CHECK_PANIC_SENTINEL) && value instanceof PanicSentinel sentinel) { + throw sentinel.getPanic(); } - assert value != null; - var conv = executeConversion(value); - if (conv == null) { - CompilerDirectives.transferToInterpreter(); - var err = ctx.getBuiltins().error().makeTypeError(this.ensoType, value, type.getName()); - throw new PanicException(err, this); + if (is(REQUIRES_CAST)) { + var ctx = EnsoContext.get(this); + if (this.ensoType == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + var builtin = ctx.getBuiltins().getByRepresentationType(type); + if (builtin == null) { + this.ensoType = ctx.getBuiltins().any(); + } else { + this.ensoType = builtin.getType(); + } + } + var conv = executeConversion(value); + if (conv == null) { + CompilerDirectives.transferToInterpreter(); + var err = ctx.getBuiltins().error().makeTypeError(this.ensoType, value, type.getName()); + throw new PanicException(err, this); + } + return type.cast(conv); + } else { + return type.cast(value); } - return type.cast(conv); } abstract Object executeConversion(Object obj); From 731f3bbe9d8c3e6903ca75f6783a4e3a4534b2a5 Mon Sep 17 00:00:00 2001 From: Jaroslav Tulach Date: Fri, 31 Jan 2025 06:23:17 +0100 Subject: [PATCH 05/26] Process warnings in ArgNode --- .../expression/builtin/BuiltinRootNode.java | 60 ++++++++++- .../enso/interpreter/dsl/MethodProcessor.java | 99 ++++--------------- 2 files changed, 78 insertions(+), 81 deletions(-) diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/BuiltinRootNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/BuiltinRootNode.java index 5294a325fc20..13a829a72c51 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/BuiltinRootNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/BuiltinRootNode.java @@ -6,6 +6,7 @@ import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.interop.TruffleObject; +import com.oracle.truffle.api.interop.UnsupportedMessageException; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.nodes.NodeInfo; import com.oracle.truffle.api.nodes.RootNode; @@ -13,9 +14,13 @@ import org.enso.interpreter.runtime.EnsoContext; import org.enso.interpreter.runtime.data.EnsoMultiValue; import org.enso.interpreter.runtime.data.Type; +import org.enso.interpreter.runtime.data.hash.EnsoHashMap; +import org.enso.interpreter.runtime.data.hash.HashMapInsertAllNode; import org.enso.interpreter.runtime.error.DataflowError; import org.enso.interpreter.runtime.error.PanicException; import org.enso.interpreter.runtime.error.PanicSentinel; +import org.enso.interpreter.runtime.warning.AppendWarningNode; +import org.enso.interpreter.runtime.warning.WarningsLibrary; import org.enso.pkg.QualifiedName; /** Root node for use by all the builtin functions. */ @@ -67,12 +72,27 @@ public void setTypeName(QualifiedName typeName) { protected static final class ArgContext { private TruffleObject returnValue; + private EnsoHashMap warnings; public ArgContext() {} public TruffleObject getReturnValue() { return returnValue; } + + public boolean hasWarnings() { + return this.warnings != null; + } + + private void addWarnings( + VirtualFrame frame, HashMapInsertAllNode insertNode, EnsoHashMap newWarnings) { + if (this.warnings == null) { + this.warnings = newWarnings; + } else { + int maxWarnings = EnsoContext.get(insertNode).getWarningsLimit(); + this.warnings = insertNode.executeInsertAll(frame, this.warnings, newWarnings, maxWarnings); + } + } } protected abstract static class ArgNode extends Node { @@ -85,8 +105,15 @@ protected abstract static class ArgNode extends Node { private final byte flags; @CompilerDirectives.CompilationFinal private Type ensoType; + @Child private WarningsLibrary warnings; + @Child private AppendWarningNode appendWarningNode; + @Child private HashMapInsertAllNode mapInsertAllNode; + ArgNode(byte flags) { this.flags = flags; + if (is(CHECK_WARNINGS)) { + this.warnings = WarningsLibrary.getFactory().createDispatched(5); + } } private boolean is(byte what) { @@ -94,7 +121,8 @@ private boolean is(byte what) { } @SuppressWarnings("unchecked") - public final T processArgument(Class type, Object value, ArgContext context) { + public final T processArgument( + VirtualFrame frame, Class type, Object value, ArgContext context) { assert value != null; if (is(CHECK_ERRORS) && value instanceof DataflowError err) { context.returnValue = err; @@ -103,6 +131,22 @@ public final T processArgument(Class type, Object value, ArgContext conte if (is(CHECK_PANIC_SENTINEL) && value instanceof PanicSentinel sentinel) { throw sentinel.getPanic(); } + if (warnings != null) { + if (warnings.hasWarnings(value)) { + if (mapInsertAllNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + this.mapInsertAllNode = HashMapInsertAllNode.build(); + } + if (this.mapInsertAllNode != null) { + try { + context.addWarnings(frame, mapInsertAllNode, warnings.getWarnings(value, false)); + value = warnings.removeWarnings(value); + } catch (UnsupportedMessageException ex) { + throw raise(RuntimeException.class, ex); + } + } + } + } if (is(REQUIRES_CAST)) { var ctx = EnsoContext.get(this); if (this.ensoType == null) { @@ -126,6 +170,15 @@ public final T processArgument(Class type, Object value, ArgContext conte } } + public final Object processWarnings(VirtualFrame frame, Object result, ArgContext context) { + assert context.warnings != null; + if (this.appendWarningNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + this.appendWarningNode = insert(AppendWarningNode.build()); + } + return appendWarningNode.executeAppend(frame, result, context.warnings); + } + abstract Object executeConversion(Object obj); @Specialization @@ -181,4 +234,9 @@ public static ArgNode create( */ } + + @SuppressWarnings("unchecked") + private static E raise(Class clazz, Throwable t) throws E { + throw (E) t; + } } diff --git a/lib/scala/interpreter-dsl/src/main/java/org/enso/interpreter/dsl/MethodProcessor.java b/lib/scala/interpreter-dsl/src/main/java/org/enso/interpreter/dsl/MethodProcessor.java index bddbf065dd20..e214f60a050a 100644 --- a/lib/scala/interpreter-dsl/src/main/java/org/enso/interpreter/dsl/MethodProcessor.java +++ b/lib/scala/interpreter-dsl/src/main/java/org/enso/interpreter/dsl/MethodProcessor.java @@ -11,7 +11,6 @@ import java.util.List; import java.util.Map; import java.util.Set; -import java.util.stream.Collectors; import javax.annotation.processing.Filer; import javax.annotation.processing.Processor; import javax.annotation.processing.RoundEnvironment; @@ -196,14 +195,7 @@ private void generateCode(MethodDefinition methodDefinition) throws IOException + " extends BuiltinRootNode implements InlineableNode.Root {"); } out.println(" private @Child " + methodDefinition.getOriginalClassName() + " bodyNode;"); - out.println( - " private @Child AppendWarningNode appendWarningNode = AppendWarningNode.build();"); - out.println( - " private @Child WarningsLibrary warnLib =" - + " WarningsLibrary.getFactory().createDispatched(5);"); - out.println( - " private @Child HashMapInsertAllNode mapInsertAllNode = HashMapInsertAllNode.build();"); - out.println(" @Children private ArgNode[] argNodes = new ArgNode[] {"); + out.println(" private @Children ArgNode[] argNodes = new ArgNode[] {"); for (MethodDefinition.ArgumentDefinition arg : methodDefinition.getArguments()) { var checkErrors = arg.shouldCheckErrors(); var checkPanicSentinel = arg.isPositional() && !arg.isSelf(); @@ -292,22 +284,13 @@ private void generateCode(MethodDefinition methodDefinition) throws IOException + " body = " + methodDefinition.getConstructorExpression() + ";"); - out.println( - " private @Child AppendWarningNode appendWarningNode =" - + " AppendWarningNode.build();"); - out.println( - " private @Child WarningsLibrary warnLib =" - + " WarningsLibrary.getFactory().createDispatched(5);"); - out.println( - " private @Child HashMapInsertAllNode mapInsertAllNode =" - + " HashMapInsertAllNode.build();"); - out.println(" @Children private ArgNode[] argNodes = new ArgNode[] {"); + out.println(" private @Children ArgNode[] argNodes = new ArgNode[] {"); for (MethodDefinition.ArgumentDefinition arg : methodDefinition.getArguments()) { var checkErrors = arg.shouldCheckErrors(); var checkPanicSentinel = arg.isPositional() && !arg.isSelf(); var checkWarnings = arg.shouldCheckWarnings(); out.println( - " ArgNode.create(" + " ArgNode.create(" + arg.isSelf() + ", " + arg.isArray() @@ -321,12 +304,10 @@ private void generateCode(MethodDefinition methodDefinition) throws IOException + checkWarnings + "),"); } - out.println(" };"); + out.println(" };"); out.println(" @Override"); out.println(" public Object call(VirtualFrame frame, Object[] args) {"); - out.println( - " return handleExecute(argNodes, frame, extra, body, appendWarningNode, warnLib," - + " mapInsertAllNode, args);"); + out.println(" return handleExecute(argNodes, frame, extra, body, args);"); out.println(" }"); out.println(" }"); out.println(); @@ -343,15 +324,13 @@ private void generateCode(MethodDefinition methodDefinition) throws IOException } else { out.println( " return handleExecute(argNodes, frame, this.internals, bodyNode," - + " this.appendWarningNode, this.warnLib, this.mapInsertAllNode," + " frame.getArguments());"); out.println(" }"); out.println( " private static Object handleExecute(ArgNode[] argNodes, VirtualFrame frame," + " Internals internals, " + methodDefinition.getOriginalClassName() - + " bodyNode, AppendWarningNode appendWarningNode, WarningsLibrary warnLib," - + " HashMapInsertAllNode mapInsertAllNode, Object[] args) {"); + + " bodyNode, Object[] args) {"); } out.println(" var prefix = internals.staticOrInstanceMethod ? 1 : 0;"); out.println(" State state = Function.ArgumentsHelper.getState(args);"); @@ -373,9 +352,11 @@ private void generateCode(MethodDefinition methodDefinition) throws IOException } out.println(" var argCtx = new ArgContext();"); boolean warningsPossible = - generateWarningsCheck(out, methodDefinition.getArguments(), "arguments"); + methodDefinition.getArguments().stream() + .filter(ArgumentDefinition::shouldCheckWarnings) + .count() + != 0; for (MethodDefinition.ArgumentDefinition ad : methodDefinition.getArguments()) { - out.println(" /*** Start of processing argument " + ad.getPosition() + " ***/"); if (ad.isImplicit()) { } else if (ad.isState()) { callArgNames.add("state"); @@ -389,22 +370,19 @@ private void generateCode(MethodDefinition methodDefinition) throws IOException callArgNames.add(mkArgumentInternalVarName(ad)); generateArgumentRead(out, ad, "arguments"); } - out.println(" /*** End of processing argument " + ad.getPosition() + " ***/"); } out.println(" if (argCtx.getReturnValue() != null) return argCtx.getReturnValue();"); - String executeCall = "bodyNode.execute(" + String.join(", ", callArgNames) + ")"; + out.println(" Object result;"); + var executeCall = "bodyNode.execute(" + String.join(", ", callArgNames) + ")"; + out.println(wrapInTryCatch("result = " + executeCall + ";", 4)); if (warningsPossible) { - out.println(" if (anyWarnings) {"); - out.println(" internals.anyWarningsProfile.enter();"); - out.println(" Object result;"); - out.println(wrapInTryCatch("result = " + executeCall + ";", 6)); - out.println( - " return appendWarningNode.executeAppend(frame, result, gatheredWarnings);"); + out.println(" if (argCtx.hasWarnings()) {"); + out.println(" return argNodes[0].processWarnings(frame, result, argCtx);"); out.println(" } else {"); - out.println(wrapInTryCatch("return " + executeCall + ";", 6)); + out.println(" return result;"); out.println(" }"); } else { - out.println(wrapInTryCatch("return " + executeCall + ";", 6)); + out.println(" return result;"); } out.println(" }"); @@ -509,13 +487,13 @@ private void generateArgumentRead( var argReference = argsArray + "[arg" + arg.getPosition() + "Idx]"; var varName = mkArgumentInternalVarName(arg); out.println( - " " + " " + arg.getTypeName() + " " + varName + " = argNodes[" + arg.getPosition() - + "].processArgument(" + + "].processArgument(frame, " + wrapperTypeName(arg) + ".class, " + argReference @@ -625,45 +603,6 @@ private void generateCheckedArgumentRead( out.println(" }"); } - private boolean generateWarningsCheck( - PrintWriter out, List arguments, String argumentsArray) { - if (true) { - return false; - } - List argsToCheck = - arguments.stream() - .filter(ArgumentDefinition::shouldCheckWarnings) - .collect(Collectors.toList()); - if (argsToCheck.isEmpty()) { - return false; - } else { - out.println(" boolean anyWarnings = false;"); - out.println(" int maxWarnings = EnsoContext.get(bodyNode).getWarningsLimit();"); - out.println(" EnsoHashMap gatheredWarnings = EnsoHashMap.empty();"); - for (var arg : argsToCheck) { - String argCode = arrayRead(argumentsArray, arg.getPosition()); - out.println( - " if (" - + arrayRead(argumentsArray, arg.getPosition()) - + " instanceof WithWarnings withWarnings) {"); - out.println( - " internals." + mkArgumentInternalVarName(arg) + "warnProfile" + ".enter();"); - out.println(" anyWarnings = true;"); - out.println(" try {"); // begin try - out.println(" var warns = warnLib.getWarnings(withWarnings, false);"); - out.println(" " + argCode + " = withWarnings.getValue();"); - out.println( - " gatheredWarnings = mapInsertAllNode.executeInsertAll(frame, gatheredWarnings," - + " warns, maxWarnings);"); - out.println(" } catch (UnsupportedMessageException e) {"); // end try - out.println(" throw CompilerDirectives.shouldNotReachHere(e);"); - out.println(" }"); // end catch - out.println(" }"); // end hasWarnings - } - return true; - } - } - /** * Dumps the information about the collected builtin methods to {@link * MethodProcessor#metadataPath()} resource file. From ecb74c5013959c1db2875ed6e542b5c3eef9b775 Mon Sep 17 00:00:00 2001 From: Jaroslav Tulach Date: Fri, 31 Jan 2025 06:56:26 +0100 Subject: [PATCH 06/26] Generate ArgNode for each positional argument --- .../expression/builtin/io/PrintlnNode.java | 1 + .../enso/interpreter/dsl/MethodProcessor.java | 105 ++++++++---------- 2 files changed, 45 insertions(+), 61 deletions(-) diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/io/PrintlnNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/io/PrintlnNode.java index c3dc5deb09a3..8b7234c36870 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/io/PrintlnNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/io/PrintlnNode.java @@ -41,6 +41,7 @@ Object doPrintText( Object message, Object nl, @Shared("interop") @CachedLibrary(limit = "10") InteropLibrary strings) { + EnsoContext ctx = EnsoContext.get(this); try { print(ctx.getOut(), strings.asString(message), strings.asString(nl)); diff --git a/lib/scala/interpreter-dsl/src/main/java/org/enso/interpreter/dsl/MethodProcessor.java b/lib/scala/interpreter-dsl/src/main/java/org/enso/interpreter/dsl/MethodProcessor.java index e214f60a050a..637367118257 100644 --- a/lib/scala/interpreter-dsl/src/main/java/org/enso/interpreter/dsl/MethodProcessor.java +++ b/lib/scala/interpreter-dsl/src/main/java/org/enso/interpreter/dsl/MethodProcessor.java @@ -195,27 +195,7 @@ private void generateCode(MethodDefinition methodDefinition) throws IOException + " extends BuiltinRootNode implements InlineableNode.Root {"); } out.println(" private @Child " + methodDefinition.getOriginalClassName() + " bodyNode;"); - out.println(" private @Children ArgNode[] argNodes = new ArgNode[] {"); - for (MethodDefinition.ArgumentDefinition arg : methodDefinition.getArguments()) { - var checkErrors = arg.shouldCheckErrors(); - var checkPanicSentinel = arg.isPositional() && !arg.isSelf(); - var checkWarnings = arg.shouldCheckWarnings(); - out.println( - " ArgNode.create(" - + arg.isSelf() - + ", " - + arg.isArray() - + ", " - + arg.requiresCast() - + ", " - + checkErrors - + ", " - + checkPanicSentinel - + ", " - + checkWarnings - + "),"); - } - out.println(" };"); + defineArgNodes(out, " ", methodDefinition); out.println(" private static final class Internals {"); out.println(" Internals(boolean s) {"); out.println(" this.staticOrInstanceMethod = s;"); @@ -284,27 +264,7 @@ private void generateCode(MethodDefinition methodDefinition) throws IOException + " body = " + methodDefinition.getConstructorExpression() + ";"); - out.println(" private @Children ArgNode[] argNodes = new ArgNode[] {"); - for (MethodDefinition.ArgumentDefinition arg : methodDefinition.getArguments()) { - var checkErrors = arg.shouldCheckErrors(); - var checkPanicSentinel = arg.isPositional() && !arg.isSelf(); - var checkWarnings = arg.shouldCheckWarnings(); - out.println( - " ArgNode.create(" - + arg.isSelf() - + ", " - + arg.isArray() - + ", " - + arg.requiresCast() - + ", " - + checkErrors - + ", " - + checkPanicSentinel - + ", " - + checkWarnings - + "),"); - } - out.println(" };"); + defineArgNodes(out, " ", methodDefinition); out.println(" @Override"); out.println(" public Object call(VirtualFrame frame, Object[] args) {"); out.println(" return handleExecute(argNodes, frame, extra, body, args);"); @@ -368,7 +328,20 @@ private void generateCode(MethodDefinition methodDefinition) throws IOException callArgNames.add("callerInfo"); } else { callArgNames.add(mkArgumentInternalVarName(ad)); - generateArgumentRead(out, ad, "arguments"); + var argReference = "arguments[arg" + ad.getPosition() + "Idx]"; + var varName = mkArgumentInternalVarName(ad); + out.println( + " " + + ad.getTypeName() + + " " + + varName + + " = argNodes[" + + ad.getPosition() + + "].processArgument(frame, " + + wrapperTypeName(ad) + + ".class, " + + argReference + + ", argCtx);"); } } out.println(" if (argCtx.getReturnValue() != null) return argCtx.getReturnValue();"); @@ -423,6 +396,34 @@ private void generateCode(MethodDefinition methodDefinition) throws IOException } } + private void defineArgNodes( + final PrintWriter out, final String sep, MethodDefinition methodDefinition) { + out.println(sep + "private @Children ArgNode[] argNodes = new ArgNode[] {"); + for (MethodDefinition.ArgumentDefinition arg : methodDefinition.getArguments()) { + if (arg.isPositional()) { + var checkErrors = arg.shouldCheckErrors(); + var checkPanicSentinel = arg.isPositional() && !arg.isSelf(); + var checkWarnings = arg.shouldCheckWarnings(); + out.println( + sep + + " ArgNode.create(" + + arg.isSelf() + + ", " + + arg.isArray() + + ", " + + arg.requiresCast() + + ", " + + checkErrors + + ", " + + checkPanicSentinel + + ", " + + checkWarnings + + "),"); + } + } + out.println(sep + "};"); + } + private String wrapInTryCatch(String statement, int indent) { var indentStr = Strings.repeat(" ", indent); var sb = new StringBuilder(); @@ -482,24 +483,6 @@ private String wrapperTypeName(MethodDefinition.ArgumentDefinition arg) { } } - private void generateArgumentRead( - PrintWriter out, MethodDefinition.ArgumentDefinition arg, String argsArray) { - var argReference = argsArray + "[arg" + arg.getPosition() + "Idx]"; - var varName = mkArgumentInternalVarName(arg); - out.println( - " " - + arg.getTypeName() - + " " - + varName - + " = argNodes[" - + arg.getPosition() - + "].processArgument(frame, " - + wrapperTypeName(arg) - + ".class, " - + argReference - + ", argCtx);"); - } - private void generateUncastedArgumentRead( PrintWriter out, MethodDefinition.ArgumentDefinition arg, String argsArray) { String varName = mkArgumentInternalVarName(arg); From 0925fa2fccb77fe666bd95d538612549aa1df058 Mon Sep 17 00:00:00 2001 From: Jaroslav Tulach Date: Fri, 31 Jan 2025 07:00:25 +0100 Subject: [PATCH 07/26] Cleaning up to address IDE's lints --- .../enso/interpreter/dsl/MethodProcessor.java | 130 ++---------------- 1 file changed, 9 insertions(+), 121 deletions(-) diff --git a/lib/scala/interpreter-dsl/src/main/java/org/enso/interpreter/dsl/MethodProcessor.java b/lib/scala/interpreter-dsl/src/main/java/org/enso/interpreter/dsl/MethodProcessor.java index 637367118257..427c2a7886ec 100644 --- a/lib/scala/interpreter-dsl/src/main/java/org/enso/interpreter/dsl/MethodProcessor.java +++ b/lib/scala/interpreter-dsl/src/main/java/org/enso/interpreter/dsl/MethodProcessor.java @@ -55,7 +55,7 @@ public boolean handleProcess(Set annotations, RoundEnviro if (elt.getKind() == ElementKind.CLASS) { try { var needsFrame = BuiltinsProcessor.checkNeedsFrame(elt); - handleTypeElement((TypeElement) elt, roundEnv, needsFrame); + handleTypeElement((TypeElement) elt, needsFrame); } catch (IOException e) { processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, e.getMessage()); } @@ -72,8 +72,7 @@ public boolean handleProcess(Set annotations, RoundEnviro return true; } - private void handleTypeElement(TypeElement element, RoundEnvironment roundEnv, Boolean needsFrame) - throws IOException { + private void handleTypeElement(TypeElement element, Boolean needsFrame) throws IOException { ExecutableElement executeMethod = element.getEnclosedElements().stream() .filter( @@ -160,10 +159,6 @@ private void handleTypeElement(TypeElement element, RoundEnvironment roundEnv, B "org.enso.interpreter.runtime.warning.WithWarnings", "org.enso.interpreter.runtime.warning.AppendWarningNode"); - /** List of exception types that should be caught from the builtin's execute method. */ - private static final List handleExceptionTypes = - List.of("UnsupportedSpecializationException"); - private void generateCode(MethodDefinition methodDefinition) throws IOException { JavaFileObject gen = processingEnv.getFiler().createSourceFile(methodDefinition.getQualifiedName()); @@ -428,7 +423,7 @@ private String wrapInTryCatch(String statement, int indent) { var indentStr = Strings.repeat(" ", indent); var sb = new StringBuilder(); sb.append(indentStr).append("try {").append("\n"); - sb.append(indentStr).append(" " + statement).append("\n"); + sb.append(indentStr).append(" ").append(statement).append("\n"); sb.append(indentStr) .append("} catch (UnsupportedSpecializationException unsupSpecEx) {") .append("\n"); @@ -483,121 +478,22 @@ private String wrapperTypeName(MethodDefinition.ArgumentDefinition arg) { } } - private void generateUncastedArgumentRead( - PrintWriter out, MethodDefinition.ArgumentDefinition arg, String argsArray) { - String varName = mkArgumentInternalVarName(arg); - out.println( - " " - + arg.getTypeName() - + " " - + varName - + " = " - + argsArray - + "[arg" - + arg.getPosition() - + "Idx];"); - } - - private void generateUncheckedArgumentRead( - PrintWriter out, MethodDefinition.ArgumentDefinition arg, String argsArray) { - String castName = "TypesGen.as" + capitalize(arg.getTypeName()); - String varName = mkArgumentInternalVarName(arg); - out.println( - " " - + arg.getTypeName() - + " " - + varName - + " = " - + castName - + "(" - + argsArray - + "[arg" - + arg.getPosition() - + "Idx]);"); - } - - private void generateUncheckedArrayCast( - PrintWriter out, MethodDefinition.ArgumentDefinition arg, String argsArray) { - String castName = arg.getTypeName(); - String varName = mkArgumentInternalVarName(arg); - out.println( - " " - + arg.getTypeName() - + " " - + varName - + " = (" - + castName - + ")" - + argsArray - + "[arg" - + arg.getPosition() - + "Idx];"); - } - - private void generateCheckedArgumentRead( - PrintWriter out, MethodDefinition.ArgumentDefinition arg, String argsArray) { - String builtinName = capitalize(arg.getTypeName()); - String castName = "TypesGen.expect" + builtinName; - String varName = mkArgumentInternalVarName(arg); - out.println(" " + arg.getTypeName() + " " + varName + ";"); - out.println(" try {"); - out.println( - " " - + varName - + " = " - + castName - + "(" - + argsArray - + "[arg" - + arg.getPosition() - + "Idx]);"); - out.println(" } catch (UnexpectedResultException e) {"); - out.println(" CompilerDirectives.transferToInterpreter();"); - out.println(" var builtins = EnsoContext.get(bodyNode).getBuiltins();"); - out.println( - " var ensoTypeName = org.enso.interpreter.runtime.type.ConstantsGen.getEnsoTypeName(\"" - + builtinName - + "\");"); - out.println(" var error = (ensoTypeName != null)"); - out.println( - " ? builtins.error().makeTypeError(ensoTypeName, arguments[arg" - + arg.getPosition() - + "Idx], \"" - + varName - + "\")"); - out.println( - " : builtins.error().makeUnsupportedArgumentsError(new Object[] { arguments[arg" - + arg.getPosition() - + "Idx] }, \"Unsupported argument for " - + varName - + " expected a '" - + builtinName - + "' but got a '\"" - + " + arguments[arg" - + arg.getPosition() - + "Idx]" - + " + \"' [\"" - + " + arguments[arg" - + arg.getPosition() - + "Idx].getClass()" - + " + \"]\"" - + ");"); - out.println(" throw new PanicException(error, bodyNode);"); - out.println(" }"); - } - /** * Dumps the information about the collected builtin methods to {@link * MethodProcessor#metadataPath()} resource file. * - *

The format of a single row in the metadata file: : + *

The format of a single row in the metadata file: + * + *

+   * "full name of the method":"class name of the root node"
+   * 
* * @param writer a writer to the metadata resource * @param pastEntries entries from the previously created metadata file, if any. Entries that * should not be appended to {@code writer} should be removed * @throws IOException */ + @Override protected void storeMetadata(Writer writer, Map pastEntries) throws IOException { for (Filer f : builtinMethods.keySet()) { @@ -631,18 +527,10 @@ protected void cleanup() { builtinMethods.clear(); } - private String warningCheck(MethodDefinition.ArgumentDefinition arg) { - return "(" + mkArgumentInternalVarName(arg) + " instanceof WithWarnings)"; - } - private String mkArgumentInternalVarName(MethodDefinition.ArgumentDefinition arg) { return "arg" + arg.getPosition(); } - private String arrayRead(String array, int index) { - return array + "[arg" + index + "Idx]"; - } - private String capitalize(String name) { return name.substring(0, 1).toUpperCase() + name.substring(1); } From 24fe8daecde213e09968fcc7102dd952de6456e1 Mon Sep 17 00:00:00 2001 From: Jaroslav Tulach Date: Fri, 31 Jan 2025 07:59:04 +0100 Subject: [PATCH 08/26] Allow null return value from processArgument --- .../org/enso/interpreter/dsl/MethodProcessor.java | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/lib/scala/interpreter-dsl/src/main/java/org/enso/interpreter/dsl/MethodProcessor.java b/lib/scala/interpreter-dsl/src/main/java/org/enso/interpreter/dsl/MethodProcessor.java index 427c2a7886ec..7b2b4430967c 100644 --- a/lib/scala/interpreter-dsl/src/main/java/org/enso/interpreter/dsl/MethodProcessor.java +++ b/lib/scala/interpreter-dsl/src/main/java/org/enso/interpreter/dsl/MethodProcessor.java @@ -322,18 +322,22 @@ private void generateCode(MethodDefinition methodDefinition) throws IOException } else if (ad.isCallerInfo()) { callArgNames.add("callerInfo"); } else { - callArgNames.add(mkArgumentInternalVarName(ad)); + var plain = ad.getTypeName(); + var boxed = wrapperTypeName(ad); + if (plain.equals(boxed)) { + callArgNames.add(mkArgumentInternalVarName(ad)); + } else { + callArgNames.add("(" + plain + ")" + mkArgumentInternalVarName(ad)); + } var argReference = "arguments[arg" + ad.getPosition() + "Idx]"; var varName = mkArgumentInternalVarName(ad); out.println( - " " - + ad.getTypeName() - + " " + " var " + varName + " = argNodes[" + ad.getPosition() + "].processArgument(frame, " - + wrapperTypeName(ad) + + boxed + ".class, " + argReference + ", argCtx);"); From f60457cffa0a212e7f779f435d64a308c056ec1e Mon Sep 17 00:00:00 2001 From: Jaroslav Tulach Date: Fri, 31 Jan 2025 09:57:52 +0100 Subject: [PATCH 09/26] Removing unused variable --- .../org/enso/interpreter/runtime/warning/AppendWarningNode.java | 1 - 1 file changed, 1 deletion(-) diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/warning/AppendWarningNode.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/warning/AppendWarningNode.java index a4dda4e9d25e..92d8c7606a06 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/warning/AppendWarningNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/warning/AppendWarningNode.java @@ -133,7 +133,6 @@ WithWarnings doWithWarnMultipleWarningsHashMap( } var maxWarns = withWarnings.maxWarnings; var warnsMap = withWarnings.warnings; - var curWarnsCnt = (int) mapSizeNode.execute(warnsMap); warnsMap = mapInsertAllNode.executeInsertAll(frame, warnsMap, newWarnsMap, maxWarns); var isLimitReached = mapSizeNode.execute(warnsMap) >= maxWarns; return new WithWarnings(withWarnings.value, withWarnings.maxWarnings, isLimitReached, warnsMap); From 8f652cb3741d0843e19b094921d1b487c7a32349 Mon Sep 17 00:00:00 2001 From: Jaroslav Tulach Date: Tue, 4 Feb 2025 07:25:37 +0100 Subject: [PATCH 10/26] Removing commented out code --- .../node/expression/builtin/BuiltinRootNode.java | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/BuiltinRootNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/BuiltinRootNode.java index 13a829a72c51..0697c11aec96 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/BuiltinRootNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/BuiltinRootNode.java @@ -220,19 +220,6 @@ public static ArgNode create( } return BuiltinRootNodeFactory.ArgNodeGen.create(flags); } - - /* - if (!arg.requiresCast()) { - generateUncastedArgumentRead(out, arg, argsArray); - } else if (arg.isSelf()) { - generateUncheckedArgumentRead(out, arg, argsArray); - } else if (arg.isArray()) { - generateUncheckedArrayCast(out, arg, argsArray); - } else { - generateCheckedArgumentRead(out, arg, argsArray); - } - - */ } @SuppressWarnings("unchecked") From e2571a1c3d558c69aed688805998cc541cc864fe Mon Sep 17 00:00:00 2001 From: Jaroslav Tulach Date: Tue, 4 Feb 2025 08:52:12 +0100 Subject: [PATCH 11/26] Insert the node when adding it as a @Child --- .../interpreter/node/expression/builtin/BuiltinRootNode.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/BuiltinRootNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/BuiltinRootNode.java index 0697c11aec96..fb5cb61fa70d 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/BuiltinRootNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/BuiltinRootNode.java @@ -135,7 +135,7 @@ public final T processArgument( if (warnings.hasWarnings(value)) { if (mapInsertAllNode == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); - this.mapInsertAllNode = HashMapInsertAllNode.build(); + this.mapInsertAllNode = insert(HashMapInsertAllNode.build()); } if (this.mapInsertAllNode != null) { try { From 91d35845f26d033bc46933cef83026fc7de8f3ae Mon Sep 17 00:00:00 2001 From: Jaroslav Tulach Date: Tue, 4 Feb 2025 09:38:03 +0100 Subject: [PATCH 12/26] Only process WithWarnings to be compatible with Warnings_Spec --- .../node/expression/builtin/BuiltinRootNode.java | 3 ++- test/Base_Tests/src/Semantic/Warnings_Spec.enso | 11 ++++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/BuiltinRootNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/BuiltinRootNode.java index fb5cb61fa70d..c1b4f88a9c08 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/BuiltinRootNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/BuiltinRootNode.java @@ -21,6 +21,7 @@ import org.enso.interpreter.runtime.error.PanicSentinel; import org.enso.interpreter.runtime.warning.AppendWarningNode; import org.enso.interpreter.runtime.warning.WarningsLibrary; +import org.enso.interpreter.runtime.warning.WithWarnings; import org.enso.pkg.QualifiedName; /** Root node for use by all the builtin functions. */ @@ -132,7 +133,7 @@ public final T processArgument( throw sentinel.getPanic(); } if (warnings != null) { - if (warnings.hasWarnings(value)) { + if (value instanceof WithWarnings ww) { if (mapInsertAllNode == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); this.mapInsertAllNode = insert(HashMapInsertAllNode.build()); diff --git a/test/Base_Tests/src/Semantic/Warnings_Spec.enso b/test/Base_Tests/src/Semantic/Warnings_Spec.enso index 7e9969f1ca4b..887a0907f7e2 100644 --- a/test/Base_Tests/src/Semantic/Warnings_Spec.enso +++ b/test/Base_Tests/src/Semantic/Warnings_Spec.enso @@ -277,11 +277,16 @@ add_specs suite_builder = suite_builder.group "Dataflow Warnings" group_builder- res . should_equal [1, 0, 1, 0] Warning.get_all res wrap_errors=True . map .value . should_equal [(Map_Error.Error 3 'warn4'), (Map_Error.Error 2 'warn3'), (Map_Error.Error 1 'warn2'), (Map_Error.Error 0 'warn1')] - res.at 0 . should_equal 1 - Warning.get_all (res.at 0) . map .value . should_equal ['warn4', 'warn3', 'warn2', 'warn1'] + elem0 = res.at 0 + elem0 . should_equal 1 + four_raw = Warning.get_all elem0 + four_map = four_raw . map .value + four_map . should_equal ['warn4', 'warn3', 'warn2', 'warn1'] slice = res.slice 1 4 - Warning.get_all slice wrap_errors=True . map .value . should_equal [(Map_Error.Error 3 'warn4'), (Map_Error.Error 2 'warn3'), (Map_Error.Error 1 'warn2'), (Map_Error.Error 0 'warn1')] + slice_warn = Warning.get_all slice wrap_errors=True + slice_map = slice_warn . map + slice_map .value . should_equal [(Map_Error.Error 3 'warn4'), (Map_Error.Error 2 'warn3'), (Map_Error.Error 1 'warn2'), (Map_Error.Error 0 'warn1')] zero = even 0 Warning.get_all zero wrap_errors=True . map .value . should_equal ["warn"+0.to_text] From 847bd9920f10ec9478c29dcc42b86ff23519026f Mon Sep 17 00:00:00 2001 From: Jaroslav Tulach Date: Tue, 4 Feb 2025 10:18:27 +0100 Subject: [PATCH 13/26] Introducing generateArguments again --- .../enso/interpreter/dsl/MethodProcessor.java | 173 ++++-------------- 1 file changed, 36 insertions(+), 137 deletions(-) diff --git a/lib/scala/interpreter-dsl/src/main/java/org/enso/interpreter/dsl/MethodProcessor.java b/lib/scala/interpreter-dsl/src/main/java/org/enso/interpreter/dsl/MethodProcessor.java index 637367118257..a54dc5e5b563 100644 --- a/lib/scala/interpreter-dsl/src/main/java/org/enso/interpreter/dsl/MethodProcessor.java +++ b/lib/scala/interpreter-dsl/src/main/java/org/enso/interpreter/dsl/MethodProcessor.java @@ -1,6 +1,5 @@ package org.enso.interpreter.dsl; -import com.google.common.base.Strings; import java.io.IOException; import java.io.PrintWriter; import java.io.Writer; @@ -195,7 +194,9 @@ private void generateCode(MethodDefinition methodDefinition) throws IOException + " extends BuiltinRootNode implements InlineableNode.Root {"); } out.println(" private @Child " + methodDefinition.getOriginalClassName() + " bodyNode;"); - defineArgNodes(out, " ", methodDefinition); + out.println(" private @Children ArgNode[] argNodes = new ArgNode[] {"); + generateArguments(methodDefinition, out); + out.println(" };"); out.println(" private static final class Internals {"); out.println(" Internals(boolean s) {"); out.println(" this.staticOrInstanceMethod = s;"); @@ -264,7 +265,9 @@ private void generateCode(MethodDefinition methodDefinition) throws IOException + " body = " + methodDefinition.getConstructorExpression() + ";"); - defineArgNodes(out, " ", methodDefinition); + out.println(" private @Children ArgNode[] argNodes = new ArgNode[] {"); + generateArguments(methodDefinition, out); + out.println(" };"); out.println(" @Override"); out.println(" public Object call(VirtualFrame frame, Object[] args) {"); out.println(" return handleExecute(argNodes, frame, extra, body, args);"); @@ -328,20 +331,7 @@ private void generateCode(MethodDefinition methodDefinition) throws IOException callArgNames.add("callerInfo"); } else { callArgNames.add(mkArgumentInternalVarName(ad)); - var argReference = "arguments[arg" + ad.getPosition() + "Idx]"; - var varName = mkArgumentInternalVarName(ad); - out.println( - " " - + ad.getTypeName() - + " " - + varName - + " = argNodes[" - + ad.getPosition() - + "].processArgument(frame, " - + wrapperTypeName(ad) - + ".class, " - + argReference - + ", argCtx);"); + generateArgumentRead(out, ad, "arguments"); } } out.println(" if (argCtx.getReturnValue() != null) return argCtx.getReturnValue();"); @@ -396,39 +386,33 @@ private void generateCode(MethodDefinition methodDefinition) throws IOException } } - private void defineArgNodes( - final PrintWriter out, final String sep, MethodDefinition methodDefinition) { - out.println(sep + "private @Children ArgNode[] argNodes = new ArgNode[] {"); + private static void generateArguments(MethodDefinition methodDefinition, final PrintWriter out) { for (MethodDefinition.ArgumentDefinition arg : methodDefinition.getArguments()) { - if (arg.isPositional()) { - var checkErrors = arg.shouldCheckErrors(); - var checkPanicSentinel = arg.isPositional() && !arg.isSelf(); - var checkWarnings = arg.shouldCheckWarnings(); - out.println( - sep - + " ArgNode.create(" - + arg.isSelf() - + ", " - + arg.isArray() - + ", " - + arg.requiresCast() - + ", " - + checkErrors - + ", " - + checkPanicSentinel - + ", " - + checkWarnings - + "),"); - } + var checkErrors = arg.shouldCheckErrors(); + var checkPanicSentinel = arg.isPositional() && !arg.isSelf(); + var checkWarnings = arg.shouldCheckWarnings(); + out.println( + " ArgNode.create(" + + arg.isSelf() + + ", " + + arg.isArray() + + ", " + + arg.requiresCast() + + ", " + + checkErrors + + ", " + + checkPanicSentinel + + ", " + + checkWarnings + + "),"); } - out.println(sep + "};"); } private String wrapInTryCatch(String statement, int indent) { - var indentStr = Strings.repeat(" ", indent); + var indentStr = " ".repeat(indent); var sb = new StringBuilder(); sb.append(indentStr).append("try {").append("\n"); - sb.append(indentStr).append(" " + statement).append("\n"); + sb.append(indentStr).append(" ").append(statement).append("\n"); sb.append(indentStr) .append("} catch (UnsupportedSpecializationException unsupSpecEx) {") .append("\n"); @@ -483,107 +467,22 @@ private String wrapperTypeName(MethodDefinition.ArgumentDefinition arg) { } } - private void generateUncastedArgumentRead( - PrintWriter out, MethodDefinition.ArgumentDefinition arg, String argsArray) { - String varName = mkArgumentInternalVarName(arg); - out.println( - " " - + arg.getTypeName() - + " " - + varName - + " = " - + argsArray - + "[arg" - + arg.getPosition() - + "Idx];"); - } - - private void generateUncheckedArgumentRead( - PrintWriter out, MethodDefinition.ArgumentDefinition arg, String argsArray) { - String castName = "TypesGen.as" + capitalize(arg.getTypeName()); - String varName = mkArgumentInternalVarName(arg); - out.println( - " " - + arg.getTypeName() - + " " - + varName - + " = " - + castName - + "(" - + argsArray - + "[arg" - + arg.getPosition() - + "Idx]);"); - } - - private void generateUncheckedArrayCast( + private void generateArgumentRead( PrintWriter out, MethodDefinition.ArgumentDefinition arg, String argsArray) { - String castName = arg.getTypeName(); - String varName = mkArgumentInternalVarName(arg); + var argReference = argsArray + "[arg" + arg.getPosition() + "Idx]"; + var varName = mkArgumentInternalVarName(arg); out.println( " " + arg.getTypeName() + " " + varName - + " = (" - + castName - + ")" - + argsArray - + "[arg" - + arg.getPosition() - + "Idx];"); - } - - private void generateCheckedArgumentRead( - PrintWriter out, MethodDefinition.ArgumentDefinition arg, String argsArray) { - String builtinName = capitalize(arg.getTypeName()); - String castName = "TypesGen.expect" + builtinName; - String varName = mkArgumentInternalVarName(arg); - out.println(" " + arg.getTypeName() + " " + varName + ";"); - out.println(" try {"); - out.println( - " " - + varName - + " = " - + castName - + "(" - + argsArray - + "[arg" - + arg.getPosition() - + "Idx]);"); - out.println(" } catch (UnexpectedResultException e) {"); - out.println(" CompilerDirectives.transferToInterpreter();"); - out.println(" var builtins = EnsoContext.get(bodyNode).getBuiltins();"); - out.println( - " var ensoTypeName = org.enso.interpreter.runtime.type.ConstantsGen.getEnsoTypeName(\"" - + builtinName - + "\");"); - out.println(" var error = (ensoTypeName != null)"); - out.println( - " ? builtins.error().makeTypeError(ensoTypeName, arguments[arg" - + arg.getPosition() - + "Idx], \"" - + varName - + "\")"); - out.println( - " : builtins.error().makeUnsupportedArgumentsError(new Object[] { arguments[arg" - + arg.getPosition() - + "Idx] }, \"Unsupported argument for " - + varName - + " expected a '" - + builtinName - + "' but got a '\"" - + " + arguments[arg" - + arg.getPosition() - + "Idx]" - + " + \"' [\"" - + " + arguments[arg" + + " = argNodes[" + arg.getPosition() - + "Idx].getClass()" - + " + \"]\"" - + ");"); - out.println(" throw new PanicException(error, bodyNode);"); - out.println(" }"); + + "].processArgument(frame, " + + wrapperTypeName(arg) + + ".class, " + + argReference + + ", argCtx);"); } /** From d6d859a85dcb59bb4791ac9c309c71f66f927f7e Mon Sep 17 00:00:00 2001 From: Jaroslav Tulach Date: Tue, 4 Feb 2025 14:48:57 +0100 Subject: [PATCH 14/26] Avoid cast when type is Object --- .../interpreter/node/expression/builtin/BuiltinRootNode.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/BuiltinRootNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/BuiltinRootNode.java index c1b4f88a9c08..56a6ad82c65d 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/BuiltinRootNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/BuiltinRootNode.java @@ -148,7 +148,7 @@ public final T processArgument( } } } - if (is(REQUIRES_CAST)) { + if (is(REQUIRES_CAST) && type != Object.class) { var ctx = EnsoContext.get(this); if (this.ensoType == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); From 4ca22265650f5dbf02e26095d677ed15972d1377 Mon Sep 17 00:00:00 2001 From: Jaroslav Tulach Date: Tue, 4 Feb 2025 17:33:57 +0100 Subject: [PATCH 15/26] Throw the sentinal to make RuntimeVisualizationsTest happier --- .../interpreter/node/expression/builtin/BuiltinRootNode.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/BuiltinRootNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/BuiltinRootNode.java index 56a6ad82c65d..9e5a5293b3cf 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/BuiltinRootNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/BuiltinRootNode.java @@ -130,10 +130,10 @@ public final T processArgument( return null; } if (is(CHECK_PANIC_SENTINEL) && value instanceof PanicSentinel sentinel) { - throw sentinel.getPanic(); + throw sentinel; } if (warnings != null) { - if (value instanceof WithWarnings ww) { + if (value instanceof WithWarnings) { if (mapInsertAllNode == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); this.mapInsertAllNode = insert(HashMapInsertAllNode.build()); From 13fc5fed151042099addeac118787aea2ab68492 Mon Sep 17 00:00:00 2001 From: Jaroslav Tulach Date: Tue, 4 Feb 2025 18:17:55 +0100 Subject: [PATCH 16/26] Only generate ArgNode for positional argument --- .../main/java/org/enso/interpreter/dsl/MethodProcessor.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/scala/interpreter-dsl/src/main/java/org/enso/interpreter/dsl/MethodProcessor.java b/lib/scala/interpreter-dsl/src/main/java/org/enso/interpreter/dsl/MethodProcessor.java index 187e8f75afd0..5dbf662c63a9 100644 --- a/lib/scala/interpreter-dsl/src/main/java/org/enso/interpreter/dsl/MethodProcessor.java +++ b/lib/scala/interpreter-dsl/src/main/java/org/enso/interpreter/dsl/MethodProcessor.java @@ -400,6 +400,9 @@ private void generateCode(MethodDefinition methodDefinition) throws IOException private static void generateArguments(MethodDefinition methodDefinition, final PrintWriter out) { for (MethodDefinition.ArgumentDefinition arg : methodDefinition.getArguments()) { + if (!arg.isPositional()) { + continue; + } var checkErrors = arg.shouldCheckErrors(); var checkPanicSentinel = arg.isPositional() && !arg.isSelf(); var checkWarnings = arg.shouldCheckWarnings(); From 934deae765ecf5fb6db9a9deb340fbb325e91197 Mon Sep 17 00:00:00 2001 From: Jaroslav Tulach Date: Wed, 5 Feb 2025 06:33:04 +0100 Subject: [PATCH 17/26] Accept simple benchmark-results.xml name --- tools/performance/engine-benchmarks/bench_tool/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/performance/engine-benchmarks/bench_tool/__init__.py b/tools/performance/engine-benchmarks/bench_tool/__init__.py index 918676fd6283..11b88f08945b 100644 --- a/tools/performance/engine-benchmarks/bench_tool/__init__.py +++ b/tools/performance/engine-benchmarks/bench_tool/__init__.py @@ -58,9 +58,9 @@ def workflow_ids(self) -> List[int]: def artifact_names(self) -> List[str]: if self == Source.ENGINE: - return ["Runtime Benchmark Report"] + return ["Runtime Benchmark Report", "benchmark-results.xml"] elif self == Source.STDLIB: - return ["Enso JMH Benchmark Report"] + return ["Enso JMH Benchmark Report", "benchmark-results.xml"] else: raise ValueError(f"Unknown source {self}") From e3ee0ea4ccb4b70bc4458c184732ac74419e4dac Mon Sep 17 00:00:00 2001 From: Jaroslav Tulach Date: Wed, 5 Feb 2025 06:33:46 +0100 Subject: [PATCH 18/26] Split the benchmarks to multiple lines --- .../bench/benchmarks/semantic/AtomBenchmarks.java | 6 +++++- .../bench/benchmarks/semantic/StringBenchmarks.java | 3 ++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/engine/runtime-benchmarks/src/main/java/org/enso/interpreter/bench/benchmarks/semantic/AtomBenchmarks.java b/engine/runtime-benchmarks/src/main/java/org/enso/interpreter/bench/benchmarks/semantic/AtomBenchmarks.java index 55c5520c6668..e0b83b271f5b 100644 --- a/engine/runtime-benchmarks/src/main/java/org/enso/interpreter/bench/benchmarks/semantic/AtomBenchmarks.java +++ b/engine/runtime-benchmarks/src/main/java/org/enso/interpreter/bench/benchmarks/semantic/AtomBenchmarks.java @@ -45,7 +45,11 @@ public class AtomBenchmarks { import Standard.Base.Data.Numbers main = length -> - generator = acc -> i -> if i == 0 then acc else @Tail_Call generator (List.Cons i acc) (i - 1) + generator = acc -> i -> + if i == 0 then acc else + list = List.Cons i acc + less = i - 1 + @Tail_Call generator list less res = generator List.Nil length res diff --git a/engine/runtime-benchmarks/src/main/java/org/enso/interpreter/bench/benchmarks/semantic/StringBenchmarks.java b/engine/runtime-benchmarks/src/main/java/org/enso/interpreter/bench/benchmarks/semantic/StringBenchmarks.java index 81fbe31c8e0a..f5b7b32881a1 100644 --- a/engine/runtime-benchmarks/src/main/java/org/enso/interpreter/bench/benchmarks/semantic/StringBenchmarks.java +++ b/engine/runtime-benchmarks/src/main/java/org/enso/interpreter/bench/benchmarks/semantic/StringBenchmarks.java @@ -35,7 +35,8 @@ public void initializeBenchmark(BenchmarkParams params) throws Exception { """ from Standard.Base import all - all_length v = v.fold 0 (sum -> str -> sum + str.length) + all_length v = v.fold 0 sum-> str-> + sum + str.length create rep len = s = "Long string".repeat rep From f211c19963357211c65597da92c8f910f940371f Mon Sep 17 00:00:00 2001 From: Jaroslav Tulach Date: Wed, 5 Feb 2025 06:34:21 +0100 Subject: [PATCH 19/26] Shield against exceptional states --- .../node/expression/builtin/BuiltinRootNode.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/BuiltinRootNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/BuiltinRootNode.java index 9e5a5293b3cf..c52f95151be4 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/BuiltinRootNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/BuiltinRootNode.java @@ -10,6 +10,7 @@ import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.nodes.NodeInfo; import com.oracle.truffle.api.nodes.RootNode; +import com.oracle.truffle.api.profiles.BranchProfile; import org.enso.interpreter.EnsoLanguage; import org.enso.interpreter.runtime.EnsoContext; import org.enso.interpreter.runtime.data.EnsoMultiValue; @@ -110,6 +111,9 @@ protected abstract static class ArgNode extends Node { @Child private AppendWarningNode appendWarningNode; @Child private HashMapInsertAllNode mapInsertAllNode; + private final BranchProfile errorsTaken = BranchProfile.create(); + private final BranchProfile sentinelTaken = BranchProfile.create(); + ArgNode(byte flags) { this.flags = flags; if (is(CHECK_WARNINGS)) { @@ -126,10 +130,12 @@ public final T processArgument( VirtualFrame frame, Class type, Object value, ArgContext context) { assert value != null; if (is(CHECK_ERRORS) && value instanceof DataflowError err) { + errorsTaken.enter(); context.returnValue = err; return null; } if (is(CHECK_PANIC_SENTINEL) && value instanceof PanicSentinel sentinel) { + sentinelTaken.enter(); throw sentinel; } if (warnings != null) { From 54751cb656d482e63b739c1f15651457c209920f Mon Sep 17 00:00:00 2001 From: Jaroslav Tulach Date: Wed, 5 Feb 2025 13:31:34 +0100 Subject: [PATCH 20/26] Removing superfluous if --- .../node/expression/builtin/BuiltinRootNode.java | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/BuiltinRootNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/BuiltinRootNode.java index c52f95151be4..b05438afa59a 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/BuiltinRootNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/BuiltinRootNode.java @@ -144,13 +144,11 @@ public final T processArgument( CompilerDirectives.transferToInterpreterAndInvalidate(); this.mapInsertAllNode = insert(HashMapInsertAllNode.build()); } - if (this.mapInsertAllNode != null) { - try { - context.addWarnings(frame, mapInsertAllNode, warnings.getWarnings(value, false)); - value = warnings.removeWarnings(value); - } catch (UnsupportedMessageException ex) { - throw raise(RuntimeException.class, ex); - } + try { + context.addWarnings(frame, mapInsertAllNode, warnings.getWarnings(value, false)); + value = warnings.removeWarnings(value); + } catch (UnsupportedMessageException ex) { + throw raise(RuntimeException.class, ex); } } } From 68a654b54057e03da855b9c9e6778db0d8e0184c Mon Sep 17 00:00:00 2001 From: Jaroslav Tulach Date: Wed, 5 Feb 2025 13:36:43 +0100 Subject: [PATCH 21/26] Removing support for IS_ARRAY --- .../node/expression/builtin/BuiltinRootNode.java | 5 ----- .../main/java/org/enso/interpreter/dsl/MethodProcessor.java | 6 ++++-- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/BuiltinRootNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/BuiltinRootNode.java index b05438afa59a..a9323a97721a 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/BuiltinRootNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/BuiltinRootNode.java @@ -99,7 +99,6 @@ private void addWarnings( protected abstract static class ArgNode extends Node { private static final byte IS_SELF = 0x01; - private static final byte IS_ARRAY = 0x02; private static final byte REQUIRES_CAST = 0x04; private static final byte CHECK_ERRORS = 0x08; private static final byte CHECK_PANIC_SENTINEL = 0x10; @@ -199,7 +198,6 @@ final Object justReturnIt(Object obj) { public static ArgNode create( boolean isSelf, - boolean isArray, boolean requiresCast, boolean checkErrors, boolean checkPanicSentinel, @@ -208,9 +206,6 @@ public static ArgNode create( if (isSelf) { flags |= IS_SELF; } - if (isArray) { - flags |= IS_ARRAY; - } if (requiresCast) { flags |= REQUIRES_CAST; } diff --git a/lib/scala/interpreter-dsl/src/main/java/org/enso/interpreter/dsl/MethodProcessor.java b/lib/scala/interpreter-dsl/src/main/java/org/enso/interpreter/dsl/MethodProcessor.java index 5dbf662c63a9..46e528d51654 100644 --- a/lib/scala/interpreter-dsl/src/main/java/org/enso/interpreter/dsl/MethodProcessor.java +++ b/lib/scala/interpreter-dsl/src/main/java/org/enso/interpreter/dsl/MethodProcessor.java @@ -406,12 +406,14 @@ private static void generateArguments(MethodDefinition methodDefinition, final P var checkErrors = arg.shouldCheckErrors(); var checkPanicSentinel = arg.isPositional() && !arg.isSelf(); var checkWarnings = arg.shouldCheckWarnings(); + if (arg.isArray()) { + out.println("/* array argument is not supported for " + arg.getName() + "*/"); + continue; + } out.println( " ArgNode.create(" + arg.isSelf() + ", " - + arg.isArray() - + ", " + arg.requiresCast() + ", " + checkErrors From 0a3ec13f05d3821fa7780b2dac404bfc6e210118 Mon Sep 17 00:00:00 2001 From: Jaroslav Tulach Date: Fri, 7 Feb 2025 07:16:49 +0100 Subject: [PATCH 22/26] Don't use InteropLibrary for primitive Enso values comparision --- .../node/expression/builtin/meta/EqualsSimpleNode.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/meta/EqualsSimpleNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/meta/EqualsSimpleNode.java index 2846a92baedc..f63d22f217de 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/meta/EqualsSimpleNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/meta/EqualsSimpleNode.java @@ -119,7 +119,7 @@ EqualsAndInfo equalsLongBigInt(long self, EnsoBigInteger other) { } } - @Specialization(guards = "isNotMulti(other)") + @Specialization(guards = {"isNotMulti(other)", "!isPrimitiveValue(other)"}) EqualsAndInfo equalsLongInterop( long self, Object other, @@ -155,7 +155,7 @@ EqualsAndInfo equalsDoubleText(double self, Text other) { return EqualsAndInfo.FALSE; } - @Specialization(guards = "!isMulti(other)") + @Specialization(guards = {"!isMulti(other)", "!isPrimitiveValue(other)"}) EqualsAndInfo equalsDoubleInterop( double self, Object other, From 21d9bc3f6394bf3763e8a4db4f030f0fbb6f4f1c Mon Sep 17 00:00:00 2001 From: Jaroslav Tulach Date: Fri, 7 Feb 2025 09:33:02 +0100 Subject: [PATCH 23/26] Use EnsoHashMap.generation when concatenating two maps together --- .../runtime/data/hash/EnsoHashMap.java | 10 ++++++++- .../data/hash/HashMapInsertAllNode.java | 10 ++++----- .../data/vector/VectorFromFunctionNode.java | 5 +++-- .../runtime/data/hash/EnsoHashMapTest.java | 22 +++++++++++++++++++ 4 files changed, 39 insertions(+), 8 deletions(-) create mode 100644 engine/runtime/src/test/java/org/enso/interpreter/runtime/data/hash/EnsoHashMapTest.java diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/hash/EnsoHashMap.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/hash/EnsoHashMap.java index bb9cfef1924c..9d1bd9cb934a 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/hash/EnsoHashMap.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/hash/EnsoHashMap.java @@ -11,11 +11,13 @@ import com.oracle.truffle.api.library.ExportLibrary; import com.oracle.truffle.api.library.ExportMessage; import com.oracle.truffle.api.profiles.ConditionProfile; +import java.util.Iterator; 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.builtin.BuiltinObject; +import org.enso.interpreter.runtime.data.hash.EnsoHashMapBuilder.Entry; import org.enso.interpreter.runtime.data.hash.EnsoHashMapBuilder.StorageEntry; import org.enso.interpreter.runtime.data.vector.ArrayLikeHelpers; @@ -135,7 +137,7 @@ Object readHashValue( } @ExportMessage - Object getHashEntriesIterator(@CachedLibrary(limit = "3") InteropLibrary interop) { + final Object getHashEntriesIterator(@CachedLibrary(limit = "3") InteropLibrary interop) { try { return interop.getIterator(getCachedVectorRepresentation()); } catch (UnsupportedMessageException e) { @@ -144,6 +146,12 @@ Object getHashEntriesIterator(@CachedLibrary(limit = "3") InteropLibrary interop } } + final Iterator getEntriesIterator( + VirtualFrame frame, HashCodeNode hashCodeNode, EqualsNode equalsNode) { + var builder = getMapBuilder(frame, true, hashCodeNode, equalsNode); + return builder.getEntriesIterator(generation); + } + @ExportMessage @TruffleBoundary @Override diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/hash/HashMapInsertAllNode.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/hash/HashMapInsertAllNode.java index 90dc16116960..ca47ce20fef6 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/hash/HashMapInsertAllNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/hash/HashMapInsertAllNode.java @@ -51,16 +51,16 @@ EnsoHashMap doEnsoHashMaps( if (otherSize == 0) { return self; } - var mapBuilder = EnsoHashMapBuilder.createWithCapacity(selfSize + otherSize); + var exactCapacity = selfSize + otherSize; + var enoughCapacity = exactCapacity + exactCapacity / 2; + var mapBuilder = EnsoHashMapBuilder.createWithCapacity(enoughCapacity); - var selfMapBuilder = self.getMapBuilder(frame, true, hashCodeNode, equalsNode); - var selfEntriesIt = selfMapBuilder.getEntriesIterator(selfMapBuilder.generation()); + var selfEntriesIt = self.getEntriesIterator(frame, hashCodeNode, equalsNode); while (selfEntriesIt.hasNext()) { var selfEntry = selfEntriesIt.next(); mapBuilder.put(frame, selfEntry.key(), selfEntry.value(), hashCodeNode, equalsNode); } - var otherMapBuilder = other.getMapBuilder(frame, true, hashCodeNode, equalsNode); - var otherEntriesIt = otherMapBuilder.getEntriesIterator(otherMapBuilder.generation()); + var otherEntriesIt = other.getEntriesIterator(frame, hashCodeNode, equalsNode); var itemsInserted = 0; while (otherEntriesIt.hasNext()) { if (itemsInserted >= maxItems) { diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/vector/VectorFromFunctionNode.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/vector/VectorFromFunctionNode.java index f75e34ab69f0..5c2f5958383e 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/vector/VectorFromFunctionNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/vector/VectorFromFunctionNode.java @@ -83,7 +83,8 @@ Object doItCached( valueToAdd = nothing; } else { var wrappedInWarn = - Warning.attach(ctx, nothing, err.getPayload(), null, appendWarningNode); + Warning.attach( + ctx, frame, nothing, err.getPayload(), null, warnsLib, appendWarningNode); valueToAdd = wrappedInWarn; } } @@ -100,7 +101,7 @@ Object doItCached( long additionalWarnsCnt = errorsEncountered - MAX_MAP_WARNINGS; var additionalWarns = additionalWarnsBuiltin.newInstance(additionalWarnsCnt); var vecWithAdditionalWarns = - Warning.attach(ctx, vector, additionalWarns, null, appendWarningNode); + Warning.attach(ctx, frame, vector, additionalWarns, null, warnsLib, appendWarningNode); return vecWithAdditionalWarns; } else { return vector; diff --git a/engine/runtime/src/test/java/org/enso/interpreter/runtime/data/hash/EnsoHashMapTest.java b/engine/runtime/src/test/java/org/enso/interpreter/runtime/data/hash/EnsoHashMapTest.java new file mode 100644 index 000000000000..fc5521735f6d --- /dev/null +++ b/engine/runtime/src/test/java/org/enso/interpreter/runtime/data/hash/EnsoHashMapTest.java @@ -0,0 +1,22 @@ +package org.enso.interpreter.runtime.data.hash; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +public class EnsoHashMapTest { + @Test + public void avoidOversaturation() { + var empty = EnsoHashMap.createEmpty(); + var insertNode = HashMapInsertNode.getUncached(); + var joinNode = HashMapInsertAllNode.getUncached(); + + var one = insertNode.execute(null, empty, 1, "Jedna"); + var two = insertNode.execute(null, one, 2, "Dvě"); + var three = insertNode.execute(null, two, 3, "Tři"); + assertEquals("Three elements: " + three, 3, three.getHashSize()); + + var againOne = joinNode.executeInsertAll(null, one, one, 10); + assertEquals("Still one: " + againOne, 1, againOne.getHashSize()); + } +} From e6af654e514dda263fa1dd4c2c7c015874b1b67b Mon Sep 17 00:00:00 2001 From: Jaroslav Tulach Date: Fri, 7 Feb 2025 09:38:41 +0100 Subject: [PATCH 24/26] Let SliceArrayVectorNode handle warnings on its own --- .../node/expression/builtin/BuiltinRootNode.java | 3 +-- .../builtin/immutable/SliceArrayVectorNode.java | 5 +++-- .../interpreter/runtime/warning/AppendWarningNode.java | 4 ++-- .../org/enso/interpreter/runtime/warning/Warning.java | 9 +++++++-- 4 files changed, 13 insertions(+), 8 deletions(-) diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/BuiltinRootNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/BuiltinRootNode.java index a9323a97721a..86eaa3997ea7 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/BuiltinRootNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/BuiltinRootNode.java @@ -22,7 +22,6 @@ import org.enso.interpreter.runtime.error.PanicSentinel; import org.enso.interpreter.runtime.warning.AppendWarningNode; import org.enso.interpreter.runtime.warning.WarningsLibrary; -import org.enso.interpreter.runtime.warning.WithWarnings; import org.enso.pkg.QualifiedName; /** Root node for use by all the builtin functions. */ @@ -138,7 +137,7 @@ public final T processArgument( throw sentinel; } if (warnings != null) { - if (value instanceof WithWarnings) { + if (warnings.hasWarnings(value)) { if (mapInsertAllNode == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); this.mapInsertAllNode = insert(HashMapInsertAllNode.build()); diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/immutable/SliceArrayVectorNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/immutable/SliceArrayVectorNode.java index fe6a78558bb0..f1247ae066c5 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/immutable/SliceArrayVectorNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/immutable/SliceArrayVectorNode.java @@ -1,6 +1,7 @@ package org.enso.interpreter.node.expression.builtin.immutable; import com.oracle.truffle.api.nodes.Node; +import org.enso.interpreter.dsl.AcceptsWarning; import org.enso.interpreter.dsl.BuiltinMethod; import org.enso.interpreter.runtime.data.vector.ArrayLikeHelpers; import org.enso.interpreter.runtime.data.vector.ArrayLikeLengthNode; @@ -14,11 +15,11 @@ public final class SliceArrayVectorNode extends Node { private SliceArrayVectorNode() {} - public static SliceArrayVectorNode build() { + static SliceArrayVectorNode build() { return new SliceArrayVectorNode(); } - Object execute(Object vector, long start, long end) { + Object execute(@AcceptsWarning Object vector, long start, long end) { var len = lengthNode.executeLength(vector); return ArrayLikeHelpers.slice(vector, start, end, len); } diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/warning/AppendWarningNode.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/warning/AppendWarningNode.java index 92d8c7606a06..849e322033ca 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/warning/AppendWarningNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/warning/AppendWarningNode.java @@ -132,8 +132,8 @@ WithWarnings doWithWarnMultipleWarningsHashMap( return withWarnings; } var maxWarns = withWarnings.maxWarnings; - var warnsMap = withWarnings.warnings; - warnsMap = mapInsertAllNode.executeInsertAll(frame, warnsMap, newWarnsMap, maxWarns); + var warnsMap = + mapInsertAllNode.executeInsertAll(frame, withWarnings.warnings, newWarnsMap, maxWarns); var isLimitReached = mapSizeNode.execute(warnsMap) >= maxWarns; return new WithWarnings(withWarnings.value, withWarnings.maxWarnings, isLimitReached, warnsMap); } diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/warning/Warning.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/warning/Warning.java index 14ede3705e1c..e96791077ed1 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/warning/Warning.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/warning/Warning.java @@ -3,11 +3,14 @@ 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.frame.VirtualFrame; import com.oracle.truffle.api.interop.InteropLibrary; import com.oracle.truffle.api.interop.StopIterationException; 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 org.enso.interpreter.dsl.AcceptsWarning; import org.enso.interpreter.dsl.Builtin; import org.enso.interpreter.runtime.EnsoContext; import org.enso.interpreter.runtime.builtin.BuiltinObject; @@ -61,12 +64,14 @@ public static Warning create(EnsoContext ctx, Object payload, Object origin) { @SuppressWarnings("generic-enso-builtin-type") public static Object attach( EnsoContext ctx, - Object value, + VirtualFrame frame, + @AcceptsWarning Object value, Object warning, Object origin, + @CachedLibrary WarningsLibrary warnings, @Cached AppendWarningNode appendWarningNode) { var warn = new Warning(warning, origin, ctx.nextSequenceId()); - return appendWarningNode.executeAppend(null, value, warn); + return appendWarningNode.executeAppend(frame, value, warn); } /** Slow version of {@link #fromMapToArray(EnsoHashMap, InteropLibrary)}. */ From 560e6b7ee0c2dc72f44041d0a3c3c0e0f3a5c773 Mon Sep 17 00:00:00 2001 From: Jaroslav Tulach Date: Fri, 7 Feb 2025 10:53:15 +0100 Subject: [PATCH 25/26] Order of some warnings got reversed --- .../org/enso/compiler/test/IfThenElseTest.java | 2 +- .../test/instrument/DebugServerInspectTest.java | 14 +++++++++----- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/engine/runtime-integration-tests/src/test/java/org/enso/compiler/test/IfThenElseTest.java b/engine/runtime-integration-tests/src/test/java/org/enso/compiler/test/IfThenElseTest.java index 0a8896377183..d393ca366be1 100644 --- a/engine/runtime-integration-tests/src/test/java/org/enso/compiler/test/IfThenElseTest.java +++ b/engine/runtime-integration-tests/src/test/java/org/enso/compiler/test/IfThenElseTest.java @@ -283,7 +283,7 @@ public void warningsInCondAndThenOrElse() throws Exception { var no = check.execute(f, y, n); assertEquals("Yes", yes.asString()); - assertWarning("GoodMaybe", yes); + assertWarning("MaybeGood", yes); assertEquals("No", no.asString()); assertWarning("BadMaybe not", no); } diff --git a/engine/runtime-integration-tests/src/test/java/org/enso/interpreter/test/instrument/DebugServerInspectTest.java b/engine/runtime-integration-tests/src/test/java/org/enso/interpreter/test/instrument/DebugServerInspectTest.java index d3c94c8c291c..edd8000ebf1d 100644 --- a/engine/runtime-integration-tests/src/test/java/org/enso/interpreter/test/instrument/DebugServerInspectTest.java +++ b/engine/runtime-integration-tests/src/test/java/org/enso/interpreter/test/instrument/DebugServerInspectTest.java @@ -165,13 +165,17 @@ public void toTextIsCalledForListings() throws Exception { assertEquals("Half", 2, r.getArrayElement(1).asInt()); assertEquals("Two", 2, r.getArrayElement(2).asInt()); assertEquals("No output printed", "", out.toString()); + assertThat( + "Stderr contains some warnings about one\n", + err.toString(), + containsString("one = 1\n ! Beware of ONE")); + assertThat( + "Stderr contains some warnings about half\n", + err.toString(), + containsString("half = 2\n ! Beware of HALF")); assertThat( "Stderr contains some warnings", err.toString(), - AllOf.allOf( - containsString("half = 2\n ! Beware of HALF"), - containsString("one = 1\n ! Beware of ONE"), - containsString("two = 2\n ! Beware of TWO\n ! Beware of HALF"), - containsString("two = 2"))); + containsString("two = 2\n ! Beware of HALF\n ! Beware of TWO")); } } From 544312884b05c20eabb491a22622a2c09c856125 Mon Sep 17 00:00:00 2001 From: Jaroslav Tulach Date: Sat, 8 Feb 2025 06:33:22 +0100 Subject: [PATCH 26/26] Avoid the need fore corepack when buildEngineDistribution --- build.sbt | 1 - 1 file changed, 1 deletion(-) diff --git a/build.sbt b/build.sbt index 2abd0982100c..8bc508a75864 100644 --- a/build.sbt +++ b/build.sbt @@ -390,7 +390,6 @@ lazy val enso = (project in file(".")) `text-buffer`, `version-output`, `ydoc-polyfill`, - `ydoc-server`, `zio-wrapper` ) .settings(Global / concurrentRestrictions += Tags.exclusive(Exclusive))